@xenknight/framework7 0.0.5 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/app/app.less +1 -1
- package/components/block/block-vars.less +6 -6
- package/components/button/button-vars.less +11 -10
- package/components/dialog/dialog-class.js +6 -3
- package/components/dialog/dialog-ios.less +10 -34
- package/components/dialog/dialog-md.less +2 -22
- package/components/dialog/dialog-rtl.css +1 -1
- package/components/dialog/dialog-vars.less +8 -10
- package/components/dialog/dialog.css +1 -1
- package/components/dialog/dialog.js +3 -3
- package/components/dialog/dialog.less +6 -25
- package/components/icon/icon-ios.less +9 -0
- package/components/icon/icon-md.less +9 -0
- package/components/icon/icon.less +2 -1
- package/components/list/list-vars.less +8 -6
- package/components/list/list.less +1 -1
- package/components/messagebar/messagebar-rtl.css +1 -1
- package/components/messagebar/messagebar-vars.less +1 -1
- package/components/messagebar/messagebar.css +1 -1
- package/components/messages/messages-rtl.css +1 -1
- package/components/messages/messages-vars.less +7 -7
- package/components/messages/messages.css +1 -1
- package/components/navbar-new/navbar-ios.less +135 -0
- package/components/navbar-new/navbar-md.less +105 -0
- package/components/navbar-new/navbar-vars.less +78 -0
- package/components/navbar-new/navbar.d.ts +77 -0
- package/components/navbar-new/navbar.js +568 -0
- package/components/navbar-new/navbar.less +268 -0
- package/components/notification/notification-class.js +6 -6
- package/components/notification/notification-ios.less +3 -8
- package/components/notification/notification-md.less +1 -20
- package/components/notification/notification-rtl.css +1 -1
- package/components/notification/notification-vars.less +13 -16
- package/components/notification/notification.css +1 -1
- package/components/notification/notification.less +13 -1
- package/components/popover/popover-class.js +21 -58
- package/components/popover/popover-ios.less +66 -2
- package/components/popover/popover-md.less +2 -27
- package/components/popover/popover-rtl.css +1 -1
- package/components/popover/popover-vars.less +2 -3
- package/components/popover/popover.css +1 -1
- package/components/popover/popover.d.ts +0 -2
- package/components/popover/popover.js +0 -1
- package/components/popover/popover.less +28 -50
- package/components/range/range-class.js +34 -27
- package/components/range/range-ios.less +60 -0
- package/components/range/range-md.less +67 -4
- package/components/range/range-rtl.css +1 -1
- package/components/range/range-vars.less +18 -13
- package/components/range/range.css +1 -1
- package/components/range/range.d.ts +3 -1
- package/components/range/range.less +11 -24
- package/components/searchbar-new/remove-diacritics.js +271 -0
- package/components/searchbar-new/searchbar-ios.less +131 -0
- package/components/searchbar-new/searchbar-md.less +153 -0
- package/components/searchbar-new/searchbar-new-class.js +592 -0
- package/components/searchbar-new/searchbar-vars.less +75 -0
- package/components/searchbar-new/searchbar.js +122 -0
- package/components/searchbar-new/searchbar.less +331 -0
- package/components/swipeout/swipeout-ios.less +37 -0
- package/components/swipeout/swipeout-md.less +56 -0
- package/components/swipeout/swipeout-rtl.css +1 -1
- package/components/swipeout/swipeout-vars.less +13 -2
- package/components/swipeout/swipeout.css +1 -1
- package/components/swipeout/swipeout.js +98 -23
- package/components/swipeout/swipeout.less +20 -44
- package/components/tabs/tabs.js +5 -0
- package/components/toast/toast-class.js +2 -2
- package/components/toast/toast-ios.less +2 -0
- package/components/toast/toast-rtl.css +1 -1
- package/components/toast/toast-vars.less +2 -4
- package/components/toast/toast.css +1 -1
- package/components/toast/toast.less +1 -1
- package/components/toolbar-new/tabbar-highlight.js +134 -0
- package/components/toolbar-new/toolbar-ios.less +193 -0
- package/components/toolbar-new/toolbar-md.less +152 -0
- package/components/toolbar-new/toolbar-vars.less +77 -0
- package/components/toolbar-new/toolbar.js +223 -0
- package/components/toolbar-new/toolbar.less +261 -0
- package/framework7-bundle-rtl.css +2606 -746
- package/framework7-bundle-rtl.min.css +12 -6
- package/framework7-bundle.css +2603 -743
- package/framework7-bundle.esm.js +11 -4
- package/framework7-bundle.js +4536 -1038
- package/framework7-bundle.js.map +1 -1
- package/framework7-bundle.less +6 -3
- package/framework7-bundle.min.css +12 -6
- package/framework7-bundle.min.js +4 -4
- package/framework7-bundle.min.js.map +1 -1
- package/framework7-lite-bundle.esm.js +11 -4
- package/framework7-lite.esm.js +11 -4
- package/framework7-lite.js +8 -1
- package/framework7-rtl.css +2212 -399
- package/framework7-rtl.min.css +11 -5
- package/framework7.css +2211 -398
- package/framework7.esm.js +11 -4
- package/framework7.js +8 -1
- package/framework7.less +6 -3
- package/framework7.min.css +11 -5
- package/package.json +1 -1
- package/shared/get-support.d.ts +0 -6
- package/shared/get-support.js +1 -20
- package/shared/material-color-utils.js +2153 -679
- package/shared/material-colors.js +97 -17
- package/shared/utils.js +18 -6
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import Framework7, {
|
|
2
|
+
CSSSelector,
|
|
3
|
+
Framework7EventsClass,
|
|
4
|
+
Framework7Plugin,
|
|
5
|
+
} from '../app/app-class.js';
|
|
6
|
+
|
|
7
|
+
export namespace Navbar {
|
|
8
|
+
interface AppMethods {
|
|
9
|
+
navbar: {
|
|
10
|
+
/** Hide navbar */
|
|
11
|
+
hide(navbarEl: HTMLElement | CSSSelector, animate?: boolean, hideStatusbar?: boolean): void;
|
|
12
|
+
/** Show navbar */
|
|
13
|
+
show(navbarEl: HTMLElement | CSSSelector, animate?: boolean): void;
|
|
14
|
+
/** Recalculate positional styles for Navbar elements. It could be useful after you change some of Navbar elements dynamically. This will have effect only in iOS theme */
|
|
15
|
+
size(navbarEl: HTMLElement | CSSSelector): void;
|
|
16
|
+
/** Get navbar HTML element by specified page element. Useful only when dynamic navbar is enabled. In this case it is out of the page container. This will have effect only in iOS theme */
|
|
17
|
+
getElByPage(pageEl: HTMLElement | CSSSelector): HTMLElement;
|
|
18
|
+
/** Get page HTML element by specified Navbar element. Useful only when dynamic navbar is enabled. In this case it is out of the page container. This will have effect only in iOS theme */
|
|
19
|
+
getPageByEl(navbarEl: HTMLElement | CSSSelector): HTMLElement;
|
|
20
|
+
/** Collapse large navbar title */
|
|
21
|
+
collapseLargeTitle(navbarEl: HTMLElement | CSSSelector): void;
|
|
22
|
+
/** Expand large navbar title */
|
|
23
|
+
expandLargeTitle(navbarEl: HTMLElement | CSSSelector): void;
|
|
24
|
+
/** Toggle large navbar title */
|
|
25
|
+
toggleLargeTitle(navbarEl: HTMLElement | CSSSelector): void;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
interface AppParams {
|
|
29
|
+
navbar?:
|
|
30
|
+
| {
|
|
31
|
+
/** Will hide Navbars on page scroll. (default false) */
|
|
32
|
+
hideOnPageScroll?: boolean;
|
|
33
|
+
/** Set to true to show hidden Navbar when scrolling reaches end of the page. (default true) */
|
|
34
|
+
showOnPageScrollEnd?: boolean;
|
|
35
|
+
/** Set to false and hidden Navbar will not become visible when you scroll page to top everytime. They will become visible only at the most top scroll position, in the beginning of the page. (default true) */
|
|
36
|
+
showOnPageScrollTop?: boolean;
|
|
37
|
+
/** When enabled then every click on navbar's title element will scroll related page to the top. (default true) */
|
|
38
|
+
scrollTopOnTitleClick?: boolean;
|
|
39
|
+
/** When enabled then it will position title at the center in iOS theme. This will have effect only in iOS theme. (default true) */
|
|
40
|
+
iosCenterTitle?: boolean;
|
|
41
|
+
/** When enabled then it will position title at the center in MD theme. This will have effect only in MD theme. (default false) */
|
|
42
|
+
mdCenterTitle?: boolean;
|
|
43
|
+
/** When enabled it will collapse large title on page scroll (default true) */
|
|
44
|
+
collapseLargeTitleOnScroll?: boolean;
|
|
45
|
+
/** When enabled it will snap page scroll to large title (default true) */
|
|
46
|
+
snapPageScrollToLargeTitle?: boolean;
|
|
47
|
+
/** When enabled it will snap page scroll to transparent title (default true) */
|
|
48
|
+
snapPageScrollToTransparentNavbar?: boolean;
|
|
49
|
+
}
|
|
50
|
+
| undefined;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
interface DomEvents {
|
|
54
|
+
/** Event will be triggered when Navbar becomes hidden */
|
|
55
|
+
'navbar:hide': () => void;
|
|
56
|
+
/** Event will be triggered when Navbar becomes visible */
|
|
57
|
+
'navbar:show': () => void;
|
|
58
|
+
/** Event will be triggered when Navbar with large title collapsed (from large navbar to usual navbar) */
|
|
59
|
+
'navbar:collapse': () => void;
|
|
60
|
+
/** Event will be triggered when Navbar with large title expanded (from usual navbar to large navbar) */
|
|
61
|
+
'navbar:expand': () => void;
|
|
62
|
+
}
|
|
63
|
+
interface AppEvents {
|
|
64
|
+
/** Event will be triggered when Navbar becomes hidden */
|
|
65
|
+
navbarHide: (el: HTMLElement) => void;
|
|
66
|
+
/** Event will be triggered when Navbar becomes visible */
|
|
67
|
+
navbarShow: (el: HTMLElement) => void;
|
|
68
|
+
/** Event will be triggered when Navbar with large title collapsed (from large navbar to usual navbar) */
|
|
69
|
+
navbarCollapse: (el: HTMLElement) => void;
|
|
70
|
+
/** Event will be triggered when Navbar with large title expanded (from usual navbar to large navbar) */
|
|
71
|
+
navbarExpand: (el: HTMLElement) => void;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
declare const NavbarComponent: Framework7Plugin;
|
|
76
|
+
|
|
77
|
+
export default NavbarComponent;
|
|
@@ -0,0 +1,568 @@
|
|
|
1
|
+
import $ from '../../shared/dom7.js';
|
|
2
|
+
import { bindMethods } from '../../shared/utils.js';
|
|
3
|
+
import { getSupport } from '../../shared/get-support.js';
|
|
4
|
+
const Navbar = {
|
|
5
|
+
size(el) {
|
|
6
|
+
const app = this;
|
|
7
|
+
const $el = $(el);
|
|
8
|
+
const $innerEl = $el.children('.navbar-new-inner');
|
|
9
|
+
if (!$innerEl.length) return;
|
|
10
|
+
const navbarNewParams = app.params.navbarNew || {};
|
|
11
|
+
const needCenterTitle = $innerEl.hasClass('navbar-new-inner-centered-title') || navbarNewParams[`${app.theme}CenterTitle`];
|
|
12
|
+
const needLeftTitle = app.theme === 'ios' && !navbarNewParams[`${app.theme}CenterTitle`];
|
|
13
|
+
if (!needCenterTitle && !needLeftTitle) return;
|
|
14
|
+
if ($el.parents('.tab:not(.tab-active)').length > 0 || $el.parents('.popup:not(.modal-in)').length > 0) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (app.theme !== 'ios' && navbarNewParams[`${app.theme}CenterTitle`]) {
|
|
18
|
+
$innerEl.addClass('navbar-new-inner-centered-title');
|
|
19
|
+
}
|
|
20
|
+
if (app.theme === 'ios' && !navbarNewParams.iosCenterTitle) {
|
|
21
|
+
$innerEl.addClass('navbar-new-inner-left-title');
|
|
22
|
+
}
|
|
23
|
+
const left = app.rtl ? $innerEl.children('.right') : $innerEl.children('.left');
|
|
24
|
+
const right = app.rtl ? $innerEl.children('.left') : $innerEl.children('.right');
|
|
25
|
+
const title = $innerEl.children('.title');
|
|
26
|
+
const noLeft = left.length === 0;
|
|
27
|
+
const noRight = right.length === 0;
|
|
28
|
+
const leftWidth = noLeft ? 0 : left.outerWidth(true);
|
|
29
|
+
const rightWidth = noRight ? 0 : right.outerWidth(true);
|
|
30
|
+
const titleWidth = title.outerWidth(true);
|
|
31
|
+
const navbarStyles = $innerEl.styles();
|
|
32
|
+
const navbarWidth = $innerEl[0].offsetWidth;
|
|
33
|
+
const navbarInnerWidth = navbarWidth - parseInt(navbarStyles.paddingLeft, 10) - parseInt(navbarStyles.paddingRight, 10);
|
|
34
|
+
let currLeft;
|
|
35
|
+
let diff;
|
|
36
|
+
if (noRight) {
|
|
37
|
+
currLeft = navbarInnerWidth - titleWidth;
|
|
38
|
+
}
|
|
39
|
+
if (noLeft) {
|
|
40
|
+
currLeft = 0;
|
|
41
|
+
}
|
|
42
|
+
if (!noLeft && !noRight) {
|
|
43
|
+
currLeft = (navbarInnerWidth - rightWidth - titleWidth + leftWidth) / 2;
|
|
44
|
+
}
|
|
45
|
+
let requiredLeft = (navbarInnerWidth - titleWidth) / 2;
|
|
46
|
+
if (navbarInnerWidth - leftWidth - rightWidth > titleWidth) {
|
|
47
|
+
if (requiredLeft < leftWidth) {
|
|
48
|
+
requiredLeft = leftWidth;
|
|
49
|
+
}
|
|
50
|
+
if (requiredLeft + titleWidth > navbarInnerWidth - rightWidth) {
|
|
51
|
+
requiredLeft = navbarInnerWidth - rightWidth - titleWidth;
|
|
52
|
+
}
|
|
53
|
+
diff = requiredLeft - currLeft;
|
|
54
|
+
} else {
|
|
55
|
+
diff = 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Center title
|
|
59
|
+
if (needCenterTitle) {
|
|
60
|
+
let titleLeft = diff;
|
|
61
|
+
if (app.rtl && noLeft && noRight && title.length > 0) titleLeft = -titleLeft;
|
|
62
|
+
title.css({
|
|
63
|
+
left: `${titleLeft}px`
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
hide(el, animate, hideStatusbar) {
|
|
68
|
+
if (animate === void 0) {
|
|
69
|
+
animate = true;
|
|
70
|
+
}
|
|
71
|
+
if (hideStatusbar === void 0) {
|
|
72
|
+
hideStatusbar = false;
|
|
73
|
+
}
|
|
74
|
+
const app = this;
|
|
75
|
+
const $el = $(el);
|
|
76
|
+
if (!$el.length) return;
|
|
77
|
+
if ($el.hasClass('navbar-new-hidden')) return;
|
|
78
|
+
let className = `navbar-new-hidden${animate ? ' navbar-new-transitioning' : ''}`;
|
|
79
|
+
const currentIsLarge = $el.find('.title-large').length;
|
|
80
|
+
if (currentIsLarge) {
|
|
81
|
+
className += ' navbar-new-large-hidden';
|
|
82
|
+
}
|
|
83
|
+
if (hideStatusbar) {
|
|
84
|
+
className += ' navbar-new-hidden-statusbar';
|
|
85
|
+
}
|
|
86
|
+
$el.transitionEnd(() => {
|
|
87
|
+
$el.removeClass('navbar-new-transitioning');
|
|
88
|
+
});
|
|
89
|
+
$el.addClass(className);
|
|
90
|
+
$el.trigger('navbar-new:hide');
|
|
91
|
+
app.emit('navbarNewHide', $el[0]);
|
|
92
|
+
},
|
|
93
|
+
show(el, animate) {
|
|
94
|
+
if (el === void 0) {
|
|
95
|
+
el = '.navbar-new-hidden';
|
|
96
|
+
}
|
|
97
|
+
if (animate === void 0) {
|
|
98
|
+
animate = true;
|
|
99
|
+
}
|
|
100
|
+
const app = this;
|
|
101
|
+
const $el = $(el);
|
|
102
|
+
if (!$el.length) return;
|
|
103
|
+
if (!$el.hasClass('navbar-new-hidden')) return;
|
|
104
|
+
if (animate) {
|
|
105
|
+
$el.addClass('navbar-new-transitioning');
|
|
106
|
+
$el.transitionEnd(() => {
|
|
107
|
+
$el.removeClass('navbar-new-transitioning');
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
$el.removeClass('navbar-new-hidden navbar-new-large-hidden navbar-new-hidden-statusbar');
|
|
111
|
+
$el.trigger('navbar-new:show');
|
|
112
|
+
app.emit('navbarNewShow', $el[0]);
|
|
113
|
+
},
|
|
114
|
+
getElByPage(page) {
|
|
115
|
+
let $pageEl;
|
|
116
|
+
let $navbarEl;
|
|
117
|
+
let pageData;
|
|
118
|
+
if (page.$navbarNewEl || page.$el) {
|
|
119
|
+
pageData = page;
|
|
120
|
+
$pageEl = page.$el;
|
|
121
|
+
} else {
|
|
122
|
+
$pageEl = $(page);
|
|
123
|
+
if ($pageEl.length > 0) pageData = $pageEl[0].f7Page;
|
|
124
|
+
}
|
|
125
|
+
if (pageData && pageData.$navbarNewEl && pageData.$navbarNewEl.length > 0) {
|
|
126
|
+
$navbarEl = pageData.$navbarNewEl;
|
|
127
|
+
} else if ($pageEl) {
|
|
128
|
+
$navbarEl = $pageEl.children('.navbar-new');
|
|
129
|
+
}
|
|
130
|
+
if (!$navbarEl || $navbarEl && $navbarEl.length === 0) return undefined;
|
|
131
|
+
return $navbarEl[0];
|
|
132
|
+
},
|
|
133
|
+
getPageByEl(navbarEl) {
|
|
134
|
+
const $navbarEl = $(navbarEl);
|
|
135
|
+
if ($navbarEl.parents('.page').length) {
|
|
136
|
+
return $navbarEl.parents('.page')[0];
|
|
137
|
+
}
|
|
138
|
+
let pageEl;
|
|
139
|
+
$navbarEl.parents('.view').find('.page').each(el => {
|
|
140
|
+
if (el && el.f7Page && el.f7Page.navbarEl && $navbarEl[0] === el.f7Page.navbarEl) {
|
|
141
|
+
pageEl = el;
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
return pageEl;
|
|
145
|
+
},
|
|
146
|
+
collapseLargeTitle(navbarEl) {
|
|
147
|
+
const app = this;
|
|
148
|
+
const $navbarEl = $(navbarEl);
|
|
149
|
+
const $pageEl = $(app.navbarNew.getPageByEl($navbarEl));
|
|
150
|
+
$navbarEl.addClass('navbar-new-large-collapsed');
|
|
151
|
+
$pageEl.eq(0).addClass('page-with-navbar-new-large-collapsed').trigger('page:navbarlargecollapsed');
|
|
152
|
+
app.emit('pageNavbarLargeCollapsed', $pageEl[0]);
|
|
153
|
+
$navbarEl.trigger('navbar-new:collapse');
|
|
154
|
+
app.emit('navbarNewCollapse', $navbarEl[0]);
|
|
155
|
+
},
|
|
156
|
+
expandLargeTitle(navbarEl) {
|
|
157
|
+
const app = this;
|
|
158
|
+
const $navbarEl = $(navbarEl);
|
|
159
|
+
const $pageEl = $(app.navbarNew.getPageByEl($navbarEl));
|
|
160
|
+
$navbarEl.removeClass('navbar-new-large-collapsed');
|
|
161
|
+
$pageEl.eq(0).removeClass('page-with-navbar-new-large-collapsed').trigger('page:navbarlargeexpanded');
|
|
162
|
+
app.emit('pageNavbarLargeExpanded', $pageEl[0]);
|
|
163
|
+
$navbarEl.trigger('navbar-new:expand');
|
|
164
|
+
app.emit('navbarNewExpand', $navbarEl[0]);
|
|
165
|
+
},
|
|
166
|
+
toggleLargeTitle(navbarEl) {
|
|
167
|
+
const app = this;
|
|
168
|
+
const $navbarEl = $(navbarEl);
|
|
169
|
+
if ($navbarEl.hasClass('navbar-new-large-collapsed')) {
|
|
170
|
+
app.navbarNew.expandLargeTitle($navbarEl);
|
|
171
|
+
} else {
|
|
172
|
+
app.navbarNew.collapseLargeTitle($navbarEl);
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
initNavbarOnScroll(pageEl, navbarEl, needHide, needCollapse, needTransparent) {
|
|
176
|
+
const app = this;
|
|
177
|
+
const support = getSupport();
|
|
178
|
+
const $pageEl = $(pageEl);
|
|
179
|
+
const $navbarEl = $(navbarEl);
|
|
180
|
+
const $titleLargeEl = $navbarEl.find('.title-large');
|
|
181
|
+
const isLarge = $titleLargeEl.length || $navbarEl.hasClass('navbar-new-large');
|
|
182
|
+
let navbarHideHeight = 44;
|
|
183
|
+
const snapPageScrollToLargeTitle = app.params.navbarNew.snapPageScrollToLargeTitle;
|
|
184
|
+
const snapPageScrollToTransparentNavbar = app.params.navbarNew.snapPageScrollToTransparentNavbar;
|
|
185
|
+
let previousScrollTop;
|
|
186
|
+
let currentScrollTop;
|
|
187
|
+
let scrollHeight;
|
|
188
|
+
let offsetHeight;
|
|
189
|
+
let reachEnd;
|
|
190
|
+
let action;
|
|
191
|
+
let navbarHidden;
|
|
192
|
+
let navbarCollapsed;
|
|
193
|
+
let navbarTitleLargeHeight;
|
|
194
|
+
let navbarOffsetHeight;
|
|
195
|
+
if (needCollapse || needHide && isLarge) {
|
|
196
|
+
navbarTitleLargeHeight = $navbarEl.css('--f7-navbar-new-large-title-height');
|
|
197
|
+
if (navbarTitleLargeHeight && navbarTitleLargeHeight.indexOf('px') >= 0) {
|
|
198
|
+
navbarTitleLargeHeight = parseInt(navbarTitleLargeHeight, 10);
|
|
199
|
+
if (Number.isNaN(navbarTitleLargeHeight) && $titleLargeEl.length) {
|
|
200
|
+
navbarTitleLargeHeight = $titleLargeEl[0].offsetHeight;
|
|
201
|
+
} else if (Number.isNaN(navbarTitleLargeHeight)) {
|
|
202
|
+
if (app.theme === 'ios') navbarTitleLargeHeight = 52;else if (app.theme === 'md') navbarTitleLargeHeight = 88;
|
|
203
|
+
}
|
|
204
|
+
} else if ($titleLargeEl.length) {
|
|
205
|
+
navbarTitleLargeHeight = $titleLargeEl[0].offsetHeight;
|
|
206
|
+
} else {
|
|
207
|
+
// eslint-disable-next-line
|
|
208
|
+
if (app.theme === 'ios') navbarTitleLargeHeight = 52;else if (app.theme === 'md') navbarTitleLargeHeight = 88;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (needHide && isLarge) {
|
|
212
|
+
navbarHideHeight += navbarTitleLargeHeight;
|
|
213
|
+
}
|
|
214
|
+
let scrollChanged;
|
|
215
|
+
let scrollContent;
|
|
216
|
+
let scrollTimeoutId;
|
|
217
|
+
let touchEndTimeoutId;
|
|
218
|
+
const touchSnapTimeout = 70;
|
|
219
|
+
const desktopSnapTimeout = 300;
|
|
220
|
+
function calcScrollableDistance() {
|
|
221
|
+
$pageEl.find('.page-content').each(pageContentEl => {
|
|
222
|
+
pageContentEl.f7ScrollableDistance = pageContentEl.scrollHeight - pageContentEl.offsetHeight;
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
function snapLargeNavbar() {
|
|
226
|
+
const inSearchbarExpanded = $navbarEl.hasClass('with-searchbar-expandable-enabled');
|
|
227
|
+
if (inSearchbarExpanded) return;
|
|
228
|
+
if (!scrollContent || currentScrollTop < 0) return;
|
|
229
|
+
if (currentScrollTop >= navbarTitleLargeHeight / 2 && currentScrollTop < navbarTitleLargeHeight) {
|
|
230
|
+
$(scrollContent).scrollTop(navbarTitleLargeHeight, 100);
|
|
231
|
+
} else if (currentScrollTop < navbarTitleLargeHeight) {
|
|
232
|
+
$(scrollContent).scrollTop(0, 200);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
function snapTransparentNavbar() {
|
|
236
|
+
const inSearchbarExpanded = $navbarEl.hasClass('with-searchbar-expandable-enabled');
|
|
237
|
+
if (inSearchbarExpanded) return;
|
|
238
|
+
if (!scrollContent || currentScrollTop < 0) return;
|
|
239
|
+
if (currentScrollTop >= navbarOffsetHeight / 2 && currentScrollTop < navbarOffsetHeight) {
|
|
240
|
+
$(scrollContent).scrollTop(navbarOffsetHeight, 100);
|
|
241
|
+
} else if (currentScrollTop < navbarOffsetHeight) {
|
|
242
|
+
$(scrollContent).scrollTop(0, 200);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
function handleNavbarTransparent() {
|
|
246
|
+
const isHidden = $navbarEl.hasClass('navbar-new-hidden');
|
|
247
|
+
const inSearchbarExpanded = $navbarEl.hasClass('with-searchbar-expandable-enabled');
|
|
248
|
+
if (inSearchbarExpanded || isHidden) return;
|
|
249
|
+
if (!navbarOffsetHeight) {
|
|
250
|
+
navbarOffsetHeight = navbarEl.offsetHeight;
|
|
251
|
+
}
|
|
252
|
+
let opacity = currentScrollTop / navbarOffsetHeight;
|
|
253
|
+
const notTransparent = $navbarEl.hasClass('navbar-new-transparent-visible');
|
|
254
|
+
opacity = Math.max(Math.min(opacity, 1), 0);
|
|
255
|
+
if (notTransparent && opacity === 1 || !notTransparent && opacity === 0) {
|
|
256
|
+
$navbarEl.find('.navbar-new-bg, .title').css('opacity', '');
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
if (notTransparent && opacity === 0) {
|
|
260
|
+
$navbarEl.trigger('navbar-new:transparenthide');
|
|
261
|
+
app.emit('navbarNewTransparentHide', $navbarEl[0]);
|
|
262
|
+
$navbarEl.removeClass('navbar-new-transparent-visible');
|
|
263
|
+
$navbarEl.find('.navbar-new-bg, .title').css('opacity', '');
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
if (!notTransparent && opacity === 1) {
|
|
267
|
+
$navbarEl.trigger('navbar-new:transparentshow');
|
|
268
|
+
app.emit('navbarNewTransparentShow', $navbarEl[0]);
|
|
269
|
+
$navbarEl.addClass('navbar-new-transparent-visible');
|
|
270
|
+
$navbarEl.find('.navbar-new-bg, .title').css('opacity', '');
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
$navbarEl.find('.navbar-new-bg, .title').css('opacity', opacity);
|
|
274
|
+
if (snapPageScrollToTransparentNavbar) {
|
|
275
|
+
if (!support.touch) {
|
|
276
|
+
clearTimeout(scrollTimeoutId);
|
|
277
|
+
scrollTimeoutId = setTimeout(() => {
|
|
278
|
+
snapTransparentNavbar();
|
|
279
|
+
}, desktopSnapTimeout);
|
|
280
|
+
} else if (touchEndTimeoutId) {
|
|
281
|
+
clearTimeout(touchEndTimeoutId);
|
|
282
|
+
touchEndTimeoutId = null;
|
|
283
|
+
touchEndTimeoutId = setTimeout(() => {
|
|
284
|
+
snapTransparentNavbar();
|
|
285
|
+
clearTimeout(touchEndTimeoutId);
|
|
286
|
+
touchEndTimeoutId = null;
|
|
287
|
+
}, touchSnapTimeout);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
let previousCollapseProgress = null;
|
|
292
|
+
let collapseProgress = null;
|
|
293
|
+
function handleLargeNavbarCollapse(pageContentEl) {
|
|
294
|
+
const isHidden = $navbarEl.hasClass('navbar-new-hidden');
|
|
295
|
+
if (isHidden) return;
|
|
296
|
+
const isLargeTransparent = $navbarEl.hasClass('navbar-new-large-transparent') || $navbarEl.hasClass('navbar-new-large') && $navbarEl.hasClass('navbar-new-transparent');
|
|
297
|
+
previousCollapseProgress = collapseProgress;
|
|
298
|
+
const scrollableDistance = Math.min(navbarTitleLargeHeight, pageContentEl.f7ScrollableDistance || navbarTitleLargeHeight);
|
|
299
|
+
collapseProgress = Math.min(Math.max(currentScrollTop / scrollableDistance, 0), 1);
|
|
300
|
+
const previousCollapseWasInMiddle = previousCollapseProgress > 0 && previousCollapseProgress < 1;
|
|
301
|
+
const inSearchbarExpanded = $navbarEl.hasClass('with-searchbar-expandable-enabled');
|
|
302
|
+
if (inSearchbarExpanded) return;
|
|
303
|
+
navbarCollapsed = $navbarEl.hasClass('navbar-new-large-collapsed');
|
|
304
|
+
const $bgEl = $navbarEl.find('.navbar-new-bg');
|
|
305
|
+
if (collapseProgress === 0 && navbarCollapsed) {
|
|
306
|
+
app.navbarNew.expandLargeTitle($navbarEl[0]);
|
|
307
|
+
} else if (collapseProgress === 1 && !navbarCollapsed) {
|
|
308
|
+
app.navbarNew.collapseLargeTitle($navbarEl[0]);
|
|
309
|
+
}
|
|
310
|
+
if (collapseProgress === 0 && navbarCollapsed || collapseProgress === 0 && previousCollapseWasInMiddle || collapseProgress === 1 && !navbarCollapsed || collapseProgress === 1 && previousCollapseWasInMiddle) {
|
|
311
|
+
if (app.theme === 'md') {
|
|
312
|
+
$navbarEl.find('.navbar-new-inner').css('overflow', '');
|
|
313
|
+
}
|
|
314
|
+
$navbarEl.find('.title').css('opacity', '');
|
|
315
|
+
$navbarEl.find('.title-large-text, .subnavbar').css('transform', '');
|
|
316
|
+
$navbarEl.find('.title-large-text').css('opacity', '');
|
|
317
|
+
if (app.theme === 'md') {
|
|
318
|
+
if (isLargeTransparent) {
|
|
319
|
+
$bgEl.css('opacity', '');
|
|
320
|
+
}
|
|
321
|
+
$bgEl.css('transform', '');
|
|
322
|
+
}
|
|
323
|
+
} else if (collapseProgress > 0 && collapseProgress < 1) {
|
|
324
|
+
if (app.theme === 'md') {
|
|
325
|
+
$navbarEl.find('.navbar-new-inner').css('overflow', 'visible');
|
|
326
|
+
}
|
|
327
|
+
$navbarEl.find('.title').css('opacity', -0.5 + collapseProgress * 1.5);
|
|
328
|
+
$navbarEl.find('.title-large-text, .subnavbar').css('transform', `translate3d(0px, ${-1 * collapseProgress * navbarTitleLargeHeight}px, 0)`);
|
|
329
|
+
$navbarEl.find('.title-large-text').css('opacity', 1 - collapseProgress * 2);
|
|
330
|
+
if (app.theme === 'md') {
|
|
331
|
+
if (isLargeTransparent) {
|
|
332
|
+
$bgEl.css('opacity', collapseProgress);
|
|
333
|
+
}
|
|
334
|
+
$bgEl.css('transform', `translate3d(0px, ${-1 * collapseProgress * navbarTitleLargeHeight}px, 0)`);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
if (snapPageScrollToLargeTitle) {
|
|
338
|
+
if (!support.touch) {
|
|
339
|
+
clearTimeout(scrollTimeoutId);
|
|
340
|
+
scrollTimeoutId = setTimeout(() => {
|
|
341
|
+
snapLargeNavbar();
|
|
342
|
+
}, desktopSnapTimeout);
|
|
343
|
+
} else if (touchEndTimeoutId) {
|
|
344
|
+
clearTimeout(touchEndTimeoutId);
|
|
345
|
+
touchEndTimeoutId = null;
|
|
346
|
+
touchEndTimeoutId = setTimeout(() => {
|
|
347
|
+
snapLargeNavbar();
|
|
348
|
+
clearTimeout(touchEndTimeoutId);
|
|
349
|
+
touchEndTimeoutId = null;
|
|
350
|
+
}, touchSnapTimeout);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
function handleTitleHideShow() {
|
|
355
|
+
if ($pageEl.hasClass('page-with-card-opened')) return;
|
|
356
|
+
scrollHeight = scrollContent.scrollHeight;
|
|
357
|
+
offsetHeight = scrollContent.offsetHeight;
|
|
358
|
+
reachEnd = currentScrollTop + offsetHeight >= scrollHeight;
|
|
359
|
+
navbarHidden = $navbarEl.hasClass('navbar-new-hidden');
|
|
360
|
+
if (reachEnd) {
|
|
361
|
+
if (app.params.navbarNew.showOnPageScrollEnd) {
|
|
362
|
+
action = 'show';
|
|
363
|
+
}
|
|
364
|
+
} else if (previousScrollTop > currentScrollTop) {
|
|
365
|
+
if (app.params.navbarNew.showOnPageScrollTop || currentScrollTop <= navbarHideHeight) {
|
|
366
|
+
action = 'show';
|
|
367
|
+
} else {
|
|
368
|
+
action = 'hide';
|
|
369
|
+
}
|
|
370
|
+
} else if (currentScrollTop > navbarHideHeight) {
|
|
371
|
+
action = 'hide';
|
|
372
|
+
} else {
|
|
373
|
+
action = 'show';
|
|
374
|
+
}
|
|
375
|
+
if (action === 'show' && navbarHidden) {
|
|
376
|
+
app.navbarNew.show($navbarEl, true, true);
|
|
377
|
+
navbarHidden = false;
|
|
378
|
+
} else if (action === 'hide' && !navbarHidden) {
|
|
379
|
+
app.navbarNew.hide($navbarEl, true, false, true);
|
|
380
|
+
navbarHidden = true;
|
|
381
|
+
}
|
|
382
|
+
previousScrollTop = currentScrollTop;
|
|
383
|
+
}
|
|
384
|
+
function handleScroll(e) {
|
|
385
|
+
scrollContent = this;
|
|
386
|
+
if (e && e.target && e.target !== scrollContent) {
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
currentScrollTop = scrollContent.scrollTop;
|
|
390
|
+
scrollChanged = currentScrollTop;
|
|
391
|
+
if (needCollapse) {
|
|
392
|
+
handleLargeNavbarCollapse(scrollContent);
|
|
393
|
+
} else if (needTransparent) {
|
|
394
|
+
handleNavbarTransparent();
|
|
395
|
+
}
|
|
396
|
+
if ($pageEl.hasClass('page-previous')) return;
|
|
397
|
+
if (needHide) {
|
|
398
|
+
handleTitleHideShow();
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
function handeTouchStart() {
|
|
402
|
+
scrollChanged = false;
|
|
403
|
+
}
|
|
404
|
+
function handleTouchEnd() {
|
|
405
|
+
clearTimeout(touchEndTimeoutId);
|
|
406
|
+
touchEndTimeoutId = null;
|
|
407
|
+
touchEndTimeoutId = setTimeout(() => {
|
|
408
|
+
if (scrollChanged !== false) {
|
|
409
|
+
if (needTransparent && !needCollapse) {
|
|
410
|
+
snapTransparentNavbar();
|
|
411
|
+
} else {
|
|
412
|
+
snapLargeNavbar();
|
|
413
|
+
}
|
|
414
|
+
clearTimeout(touchEndTimeoutId);
|
|
415
|
+
touchEndTimeoutId = null;
|
|
416
|
+
}
|
|
417
|
+
}, touchSnapTimeout);
|
|
418
|
+
}
|
|
419
|
+
$pageEl.on('scroll', '.page-content', handleScroll, true);
|
|
420
|
+
if (support.touch && (needCollapse && snapPageScrollToLargeTitle || needTransparent && snapPageScrollToTransparentNavbar)) {
|
|
421
|
+
app.on('touchstart:passive', handeTouchStart);
|
|
422
|
+
app.on('touchend:passive', handleTouchEnd);
|
|
423
|
+
}
|
|
424
|
+
calcScrollableDistance();
|
|
425
|
+
if (needCollapse || needTransparent) {
|
|
426
|
+
$pageEl.find('.page-content').each(pageContentEl => {
|
|
427
|
+
if (pageContentEl.scrollTop > 0) handleScroll.call(pageContentEl);
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
app.on('resize', calcScrollableDistance);
|
|
431
|
+
$pageEl[0].f7DetachNavbarNewScrollHandlers = function f7DetachNavbarNewScrollHandlers() {
|
|
432
|
+
app.off('resize', calcScrollableDistance);
|
|
433
|
+
delete $pageEl[0].f7DetachNavbarNewScrollHandlers;
|
|
434
|
+
$pageEl.off('scroll', '.page-content', handleScroll, true);
|
|
435
|
+
if (support.touch && (needCollapse && snapPageScrollToLargeTitle || needTransparent && snapPageScrollToTransparentNavbar)) {
|
|
436
|
+
app.off('touchstart:passive', handeTouchStart);
|
|
437
|
+
app.off('touchend:passive', handleTouchEnd);
|
|
438
|
+
}
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
};
|
|
442
|
+
export default {
|
|
443
|
+
name: 'navbar-new',
|
|
444
|
+
create() {
|
|
445
|
+
const app = this;
|
|
446
|
+
bindMethods(app, {
|
|
447
|
+
navbarNew: Navbar
|
|
448
|
+
});
|
|
449
|
+
},
|
|
450
|
+
params: {
|
|
451
|
+
navbarNew: {
|
|
452
|
+
scrollTopOnTitleClick: true,
|
|
453
|
+
iosCenterTitle: true,
|
|
454
|
+
mdCenterTitle: false,
|
|
455
|
+
hideOnPageScroll: false,
|
|
456
|
+
showOnPageScrollEnd: true,
|
|
457
|
+
showOnPageScrollTop: true,
|
|
458
|
+
collapseLargeTitleOnScroll: true,
|
|
459
|
+
snapPageScrollToLargeTitle: true,
|
|
460
|
+
snapPageScrollToTransparentNavbar: true
|
|
461
|
+
}
|
|
462
|
+
},
|
|
463
|
+
on: {
|
|
464
|
+
'panelBreakpoint panelCollapsedBreakpoint panelResize viewResize resize viewMasterDetailBreakpoint': function onPanelResize() {
|
|
465
|
+
const app = this;
|
|
466
|
+
$('.navbar-new').each(navbarEl => {
|
|
467
|
+
app.navbarNew.size(navbarEl);
|
|
468
|
+
});
|
|
469
|
+
},
|
|
470
|
+
pageBeforeRemove(page) {
|
|
471
|
+
if (page.$el[0].f7DetachNavbarNewScrollHandlers) {
|
|
472
|
+
page.$el[0].f7DetachNavbarNewScrollHandlers();
|
|
473
|
+
}
|
|
474
|
+
},
|
|
475
|
+
pageReinit(page) {
|
|
476
|
+
const app = this;
|
|
477
|
+
const $navbarEl = $(app.navbarNew.getElByPage(page));
|
|
478
|
+
if (!$navbarEl || $navbarEl.length === 0) return;
|
|
479
|
+
app.navbarNew.size($navbarEl);
|
|
480
|
+
},
|
|
481
|
+
pageInit(page) {
|
|
482
|
+
const app = this;
|
|
483
|
+
const $navbarEl = $(app.navbarNew.getElByPage(page));
|
|
484
|
+
if (!$navbarEl || $navbarEl.length === 0) return;
|
|
485
|
+
|
|
486
|
+
// Size
|
|
487
|
+
app.navbarNew.size($navbarEl);
|
|
488
|
+
|
|
489
|
+
// Need Collapse On Scroll
|
|
490
|
+
let needCollapseOnScrollHandler;
|
|
491
|
+
if ($navbarEl.find('.title-large').length > 0) {
|
|
492
|
+
$navbarEl.addClass('navbar-new-large');
|
|
493
|
+
}
|
|
494
|
+
if ($navbarEl.hasClass('navbar-new-large')) {
|
|
495
|
+
if (app.params.navbarNew.collapseLargeTitleOnScroll) needCollapseOnScrollHandler = true;
|
|
496
|
+
page.$el.addClass('page-with-navbar-new-large');
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
// Need transparent on scroll
|
|
500
|
+
let needTransparentOnScroll;
|
|
501
|
+
if (!needCollapseOnScrollHandler && $navbarEl.hasClass('navbar-new-transparent')) {
|
|
502
|
+
needTransparentOnScroll = true;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
// Need Hide On Scroll
|
|
506
|
+
let needHideOnScrollHandler;
|
|
507
|
+
if (app.params.navbarNew.hideOnPageScroll || page.$el.find('.hide-navbar-new-on-scroll').length || page.$el.hasClass('hide-navbar-new-on-scroll') || page.$el.find('.hide-bars-on-scroll').length || page.$el.hasClass('hide-bars-on-scroll')) {
|
|
508
|
+
if (page.$el.find('.keep-navbar-new-on-scroll').length || page.$el.hasClass('keep-navbar-new-on-scroll') || page.$el.find('.keep-bars-on-scroll').length || page.$el.hasClass('keep-bars-on-scroll')) {
|
|
509
|
+
needHideOnScrollHandler = false;
|
|
510
|
+
} else {
|
|
511
|
+
needHideOnScrollHandler = true;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
if (needCollapseOnScrollHandler || needHideOnScrollHandler || needTransparentOnScroll) {
|
|
515
|
+
app.navbarNew.initNavbarOnScroll(page.el, $navbarEl[0], needHideOnScrollHandler, needCollapseOnScrollHandler, needTransparentOnScroll);
|
|
516
|
+
}
|
|
517
|
+
},
|
|
518
|
+
'panelOpen panelSwipeOpen modalOpen': function onPanelModalOpen(instance) {
|
|
519
|
+
const app = this;
|
|
520
|
+
instance.$el.find('.navbar-new').each(navbarEl => {
|
|
521
|
+
app.navbarNew.size(navbarEl);
|
|
522
|
+
});
|
|
523
|
+
},
|
|
524
|
+
tabShow(tabEl) {
|
|
525
|
+
const app = this;
|
|
526
|
+
$(tabEl).find('.navbar-new').each(navbarEl => {
|
|
527
|
+
app.navbarNew.size(navbarEl);
|
|
528
|
+
});
|
|
529
|
+
}
|
|
530
|
+
},
|
|
531
|
+
clicks: {
|
|
532
|
+
'.navbar-new .title': function onTitleClick($clickedEl, clickedData, e) {
|
|
533
|
+
const app = this;
|
|
534
|
+
if (!app.params.navbarNew.scrollTopOnTitleClick) return;
|
|
535
|
+
if ($(e.target).closest('a, button').length > 0) {
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
let $pageContentEl;
|
|
539
|
+
|
|
540
|
+
// Find active page
|
|
541
|
+
const $navbarEl = $clickedEl.parents('.navbar-new');
|
|
542
|
+
|
|
543
|
+
// Static Layout
|
|
544
|
+
$pageContentEl = $navbarEl.parents('.page-content');
|
|
545
|
+
if ($pageContentEl.length === 0) {
|
|
546
|
+
// Fixed Layout
|
|
547
|
+
if ($navbarEl.parents('.page').length > 0) {
|
|
548
|
+
$pageContentEl = $navbarEl.parents('.page').find('.page-content');
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
if ($pageContentEl && $pageContentEl.length > 0) {
|
|
552
|
+
// Check for tab
|
|
553
|
+
if ($pageContentEl.hasClass('tab')) {
|
|
554
|
+
$pageContentEl = $pageContentEl.parent('.tabs').children('.page-content.tab-active');
|
|
555
|
+
}
|
|
556
|
+
if ($pageContentEl.length > 0) $pageContentEl.scrollTop(0, 300);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
},
|
|
560
|
+
vnode: {
|
|
561
|
+
'navbar-new': {
|
|
562
|
+
postpatch(vnode) {
|
|
563
|
+
const app = this;
|
|
564
|
+
app.navbarNew.size(vnode.elm);
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
};
|