1 | import { h, r as registerInstance, c as createEvent, H as Host, g as getElement } from './index-8809c729.js';
|
2 | import Taro from '@tarojs/taro';
|
3 | import { c as classnames } from './index-1d8e8acd.js';
|
4 |
|
5 | const splitUrl = _url => {
|
6 | let url = _url || '';
|
7 | let pos;
|
8 | const res = {
|
9 | path: null,
|
10 | query: null,
|
11 | fragment: null
|
12 | };
|
13 | pos = url.indexOf('#');
|
14 | if (pos > -1) {
|
15 | res.fragment = url.substring(pos + 1);
|
16 | url = url.substring(0, pos);
|
17 | }
|
18 | pos = url.indexOf('?');
|
19 | if (pos > -1) {
|
20 | res.query = url.substring(pos + 1);
|
21 | url = url.substring(0, pos);
|
22 | }
|
23 | res.path = url;
|
24 | return res;
|
25 | };
|
26 |
|
27 |
|
28 |
|
29 | const addLeadingSlash = (url = '') => (url.charAt(0) === '/' ? url : '/' + url);
|
30 | const hasBasename = (path = '', prefix = '') => new RegExp('^' + prefix + '(\\/|\\?|#|$)', 'i').test(path) || path === prefix;
|
31 | const stripBasename = (path = '', prefix = '') => hasBasename(path, prefix) ? path.substring(prefix.length) : path;
|
32 | const stripSuffix = (path = '', suffix = '') => path.includes(suffix) ? path.substring(0, path.length - suffix.length) : path;
|
33 |
|
34 | function isAbsolute(pathname) {
|
35 | return pathname.charAt(0) === '/';
|
36 | }
|
37 |
|
38 |
|
39 | function spliceOne(list, index) {
|
40 | for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1) {
|
41 | list[i] = list[k];
|
42 | }
|
43 |
|
44 | list.pop();
|
45 | }
|
46 |
|
47 |
|
48 | function resolvePathname(to, from) {
|
49 | if (from === undefined) from = '';
|
50 |
|
51 | var toParts = (to && to.split('/')) || [];
|
52 | var fromParts = (from && from.split('/')) || [];
|
53 |
|
54 | var isToAbs = to && isAbsolute(to);
|
55 | var isFromAbs = from && isAbsolute(from);
|
56 | var mustEndAbs = isToAbs || isFromAbs;
|
57 |
|
58 | if (to && isAbsolute(to)) {
|
59 |
|
60 | fromParts = toParts;
|
61 | } else if (toParts.length) {
|
62 |
|
63 | fromParts.pop();
|
64 | fromParts = fromParts.concat(toParts);
|
65 | }
|
66 |
|
67 | if (!fromParts.length) return '/';
|
68 |
|
69 | var hasTrailingSlash;
|
70 | if (fromParts.length) {
|
71 | var last = fromParts[fromParts.length - 1];
|
72 | hasTrailingSlash = last === '.' || last === '..' || last === '';
|
73 | } else {
|
74 | hasTrailingSlash = false;
|
75 | }
|
76 |
|
77 | var up = 0;
|
78 | for (var i = fromParts.length; i >= 0; i--) {
|
79 | var part = fromParts[i];
|
80 |
|
81 | if (part === '.') {
|
82 | spliceOne(fromParts, i);
|
83 | } else if (part === '..') {
|
84 | spliceOne(fromParts, i);
|
85 | up++;
|
86 | } else if (up) {
|
87 | spliceOne(fromParts, i);
|
88 | up--;
|
89 | }
|
90 | }
|
91 |
|
92 | if (!mustEndAbs) for (; up--; up) fromParts.unshift('..');
|
93 |
|
94 | if (
|
95 | mustEndAbs &&
|
96 | fromParts[0] !== '' &&
|
97 | (!fromParts[0] || !isAbsolute(fromParts[0]))
|
98 | )
|
99 | fromParts.unshift('');
|
100 |
|
101 | var result = fromParts.join('/');
|
102 |
|
103 | if (hasTrailingSlash && result.substr(-1) !== '/') result += '/';
|
104 |
|
105 | return result;
|
106 | }
|
107 |
|
108 | const TabbarItem = ({ index, isSelected = false, textColor, iconPath, badgeText, showRedDot = false, text, onSelect }) => {
|
109 | const className = classnames('weui-tabbar__item', {
|
110 | 'weui-bar__item_on': isSelected
|
111 | });
|
112 | const badgeStyle = {
|
113 | position: 'absolute',
|
114 | top: '-2px',
|
115 | right: '-13px'
|
116 | };
|
117 | const dotStyle = {
|
118 | position: 'absolute',
|
119 | top: '0',
|
120 | right: '-6px'
|
121 | };
|
122 | function onClick() {
|
123 | onSelect(index);
|
124 | }
|
125 | return (h("a", { key: index, href: 'javascript:;', class: className, onClick: onClick },
|
126 | h("span", { style: { display: 'inline-block', position: 'relative' } },
|
127 | h("img", { src: iconPath, alt: '', class: 'weui-tabbar__icon' }),
|
128 | !!badgeText && (h("span", { class: 'weui-badge taro-tabbar-badge', style: badgeStyle }, badgeText)),
|
129 | showRedDot && (h("span", { class: 'weui-badge weui-badge_dot', style: dotStyle }))),
|
130 | h("p", { class: 'weui-tabbar__label', style: { color: textColor } }, text)));
|
131 | };
|
132 |
|
133 | const indexCss = "html,body{height:100%}#app{height:100%}.taro-tabbar__border-white::before{border-top-color:#fff !important}.taro-tabbar__container{display:-ms-flexbox;display:flex;overflow:hidden;-ms-flex-direction:column;flex-direction:column;height:100%}.taro-tabbar__panel{overflow:auto;position:relative;-ms-flex:1;flex:1;-webkit-overflow-scrolling:auto}.taro-tabbar__tabbar{position:relative;width:100%;height:50px;-webkit-transition:bottom 0.2s, top 0.2s;transition:bottom 0.2s, top 0.2s}.taro-tabbar__tabbar-top{top:0}.taro-tabbar__tabbar-bottom{bottom:0;margin-bottom:constant(safe-area-inset-bottom);margin-bottom:env(safe-area-inset-bottom)}.taro-tabbar__tabbar-hide{display:none}.taro-tabbar__tabbar-slideout{top:-52px;-ms-flex:0 0;flex:0 0}.taro-tabbar__panel+.taro-tabbar__tabbar-slideout{top:auto;bottom:-52px}";
|
134 |
|
135 | const STATUS_SHOW = 0;
|
136 | const STATUS_HIDE = 1;
|
137 | const STATUS_SLIDEOUT = 2;
|
138 | const basicTabBarClassName = 'taro-tabbar__tabbar';
|
139 | const hideTabBarClassName = 'taro-tabbar__tabbar-hide';
|
140 | const hideTabBarWithAnimationClassName = 'taro-tabbar__tabbar-slideout';
|
141 | let Tabbar = class {
|
142 | constructor(hostRef) {
|
143 | registerInstance(this, hostRef);
|
144 | this.onLongPress = createEvent(this, "longpress", 7);
|
145 | this.homePage = '';
|
146 | this.customRoutes = [];
|
147 | this.tabbarPos = 'bottom';
|
148 | this.selectedIndex = -1;
|
149 | this.status = STATUS_SHOW;
|
150 | this.getOriginUrl = (url) => {
|
151 | const customRoute = this.customRoutes.filter(([, customUrl]) => {
|
152 | const pathA = splitUrl(customUrl).path;
|
153 | const pathB = splitUrl(url).path;
|
154 | return pathA === pathB;
|
155 | });
|
156 | return stripSuffix(customRoute.length ? customRoute[0][0] : url, '.html');
|
157 | };
|
158 | this.getSelectedIndex = (url) => {
|
159 | let foundIndex = -1;
|
160 | this.list.forEach(({ pagePath }, idx) => {
|
161 | const pathA = splitUrl(url).path;
|
162 | const pathB = splitUrl(pagePath).path;
|
163 | if (pathA === pathB) {
|
164 | foundIndex = idx;
|
165 | }
|
166 | });
|
167 | return foundIndex;
|
168 | };
|
169 | this.switchTab = (index) => {
|
170 | this.selectedIndex = index;
|
171 | Taro.switchTab({
|
172 | url: this.list[index].pagePath
|
173 | });
|
174 | };
|
175 | this.switchTabHandler = ({ url, successHandler, errorHandler }) => {
|
176 | const currentUrl = this.getOriginUrl(this.getCurrentUrl() || this.homePage);
|
177 | const nextTab = resolvePathname(url, currentUrl);
|
178 | const foundIndex = this.getSelectedIndex(nextTab);
|
179 | if (foundIndex > -1) {
|
180 | this.switchTab(foundIndex);
|
181 | successHandler({
|
182 | errMsg: 'switchTab:ok'
|
183 | });
|
184 | }
|
185 | else {
|
186 | errorHandler({
|
187 | errMsg: `switchTab:fail page "${nextTab}" is not found`
|
188 | });
|
189 | }
|
190 | };
|
191 | this.routerChangeHandler = (options) => {
|
192 | var _a;
|
193 | const to = (_a = options === null || options === void 0 ? void 0 : options.toLocation) === null || _a === void 0 ? void 0 : _a.path;
|
194 | let currentPage;
|
195 | if (typeof to === 'string') {
|
196 | const routerBasename = this.conf.basename || '/';
|
197 | currentPage = stripBasename(addLeadingSlash(to || this.homePage), routerBasename) || '/';
|
198 | }
|
199 | else {
|
200 | currentPage = this.getCurrentUrl();
|
201 | }
|
202 | this.selectedIndex = this.getSelectedIndex(this.getOriginUrl(currentPage));
|
203 | };
|
204 | this.setTabBarBadgeHandler = ({ index, text, successHandler, errorHandler }) => {
|
205 | const list = [...this.list];
|
206 | if (index in list) {
|
207 | list[index].showRedDot = false;
|
208 | list[index].badgeText = text;
|
209 | successHandler({
|
210 | errMsg: 'setTabBarBadge:ok'
|
211 | });
|
212 | }
|
213 | else {
|
214 | errorHandler({
|
215 | errMsg: 'setTabBarBadge:fail tabbar item not found'
|
216 | });
|
217 | }
|
218 | this.list = list;
|
219 | };
|
220 | this.removeTabBarBadgeHandler = ({ index, successHandler, errorHandler }) => {
|
221 | const list = [...this.list];
|
222 | if (index in list) {
|
223 | list[index].badgeText = null;
|
224 | list[index].badgeText = null;
|
225 | successHandler({
|
226 | errMsg: 'removeTabBarBadge:ok'
|
227 | });
|
228 | }
|
229 | else {
|
230 | errorHandler({
|
231 | errMsg: 'removeTabBarBadge:fail tabbar item not found'
|
232 | });
|
233 | }
|
234 | this.list = list;
|
235 | };
|
236 | this.showTabBarRedDotHandler = ({ index, successHandler, errorHandler }) => {
|
237 | const list = [...this.list];
|
238 | if (index in list) {
|
239 | list[index].badgeText = null;
|
240 | list[index].showRedDot = true;
|
241 | successHandler({
|
242 | errMsg: 'showTabBarRedDot:ok'
|
243 | });
|
244 | }
|
245 | else {
|
246 | errorHandler({
|
247 | errMsg: 'showTabBarRedDot:fail tabbar item not found'
|
248 | });
|
249 | }
|
250 | this.list = list;
|
251 | };
|
252 | this.hideTabBarRedDotHandler = ({ index, successHandler, errorHandler }) => {
|
253 | const list = [...this.list];
|
254 | if (index in list) {
|
255 | list[index].showRedDot = false;
|
256 | successHandler({
|
257 | errMsg: 'hideTabBarRedDot:ok'
|
258 | });
|
259 | }
|
260 | else {
|
261 | errorHandler({
|
262 | errMsg: 'hideTabBarRedDot:fail tabbar item not found'
|
263 | });
|
264 | }
|
265 | this.list = list;
|
266 | };
|
267 | this.showTabBarHandler = ({ successHandler }) => {
|
268 | this.status = STATUS_SHOW;
|
269 | successHandler({
|
270 | errMsg: 'showTabBar:ok'
|
271 | });
|
272 | };
|
273 | this.hideTabBarHandler = ({ animation, successHandler }) => {
|
274 | this.status = animation ? STATUS_SLIDEOUT : STATUS_HIDE;
|
275 | successHandler({
|
276 | errMsg: 'hideTabBar:ok'
|
277 | });
|
278 | };
|
279 | this.setTabBarStyleHandler = ({ color, selectedColor, backgroundColor, borderStyle, successHandler }) => {
|
280 | if (backgroundColor)
|
281 | this.backgroundColor = backgroundColor;
|
282 | if (borderStyle)
|
283 | this.borderStyle = borderStyle;
|
284 | if (color)
|
285 | this.color = color;
|
286 | if (selectedColor)
|
287 | this.selectedColor = selectedColor;
|
288 | successHandler({
|
289 | errMsg: 'setTabBarStyle:ok'
|
290 | });
|
291 | };
|
292 | this.setTabBarItemHandler = ({ index, iconPath, selectedIconPath, text, successHandler, errorHandler }) => {
|
293 | const list = [...this.list];
|
294 | if (index in list) {
|
295 | if (iconPath)
|
296 | list[index].iconPath = iconPath;
|
297 | if (selectedIconPath)
|
298 | list[index].selectedIconPath = selectedIconPath;
|
299 | if (text)
|
300 | list[index].text = text;
|
301 | successHandler({
|
302 | errMsg: 'setTabBarItem:ok'
|
303 | });
|
304 | }
|
305 | else {
|
306 | errorHandler({
|
307 | errMsg: 'setTabBarItem:fail tabbar item not found'
|
308 | });
|
309 | }
|
310 | this.list = list;
|
311 | };
|
312 | const list = this.conf.list;
|
313 | const customRoutes = this.conf.customRoutes;
|
314 | if (Object.prototype.toString.call(list) !== '[object Array]' ||
|
315 | list.length < 2 ||
|
316 | list.length > 5) {
|
317 | throw new Error('tabBar 配置错误');
|
318 | }
|
319 | this.homePage = addLeadingSlash(this.conf.homePage);
|
320 | for (let key in customRoutes) {
|
321 | const path = customRoutes[key];
|
322 | key = addLeadingSlash(key);
|
323 | if (typeof path === 'string') {
|
324 | this.customRoutes.push([key, addLeadingSlash(path)]);
|
325 | }
|
326 | else if ((path === null || path === void 0 ? void 0 : path.length) > 0) {
|
327 | this.customRoutes.push(...path.map(p => [key, addLeadingSlash(p)]));
|
328 | }
|
329 | }
|
330 | list.forEach(item => {
|
331 | if (item.pagePath.indexOf('/') !== 0) {
|
332 | item.pagePath = '/' + item.pagePath;
|
333 | }
|
334 | });
|
335 | this.list = list;
|
336 | this.borderStyle = this.conf.borderStyle;
|
337 | this.backgroundColor = this.conf.backgroundColor;
|
338 | this.color = this.conf.color;
|
339 | this.selectedColor = this.conf.selectedColor;
|
340 | }
|
341 | getCurrentUrl() {
|
342 | const routerMode = this.conf.mode;
|
343 | const routerBasename = this.conf.basename || '/';
|
344 | let url;
|
345 | if (routerMode === 'hash') {
|
346 | const href = window.location.href;
|
347 | const hashIndex = href.indexOf('#');
|
348 | url = hashIndex === -1
|
349 | ? ''
|
350 | : href.substring(hashIndex + 1);
|
351 | }
|
352 | else {
|
353 | url = location.pathname;
|
354 | }
|
355 | const processedUrl = addLeadingSlash(stripBasename(url, routerBasename));
|
356 | return decodeURI(processedUrl === '/' ? this.homePage : processedUrl);
|
357 | }
|
358 | bindEvent() {
|
359 | Taro.eventCenter.on('__taroRouterChange', this.routerChangeHandler);
|
360 | Taro.eventCenter.on('__taroSwitchTab', this.switchTabHandler);
|
361 | Taro.eventCenter.on('__taroSetTabBarBadge', this.setTabBarBadgeHandler);
|
362 | Taro.eventCenter.on('__taroRemoveTabBarBadge', this.removeTabBarBadgeHandler);
|
363 | Taro.eventCenter.on('__taroShowTabBarRedDotHandler', this.showTabBarRedDotHandler);
|
364 | Taro.eventCenter.on('__taroHideTabBarRedDotHandler', this.hideTabBarRedDotHandler);
|
365 | Taro.eventCenter.on('__taroShowTabBar', this.showTabBarHandler);
|
366 | Taro.eventCenter.on('__taroHideTabBar', this.hideTabBarHandler);
|
367 | Taro.eventCenter.on('__taroSetTabBarStyle', this.setTabBarStyleHandler);
|
368 | Taro.eventCenter.on('__taroSetTabBarItem', this.setTabBarItemHandler);
|
369 | }
|
370 | removeEvent() {
|
371 | Taro.eventCenter.off('__taroRouterChange', this.routerChangeHandler);
|
372 | Taro.eventCenter.off('__taroSwitchTab', this.switchTabHandler);
|
373 | Taro.eventCenter.off('__taroSetTabBarBadge', this.setTabBarBadgeHandler);
|
374 | Taro.eventCenter.off('__taroRemoveTabBarBadge', this.removeTabBarBadgeHandler);
|
375 | Taro.eventCenter.off('__taroShowTabBarRedDotHandler', this.showTabBarRedDotHandler);
|
376 | Taro.eventCenter.off('__taroHideTabBarRedDotHandler', this.hideTabBarRedDotHandler);
|
377 | Taro.eventCenter.off('__taroShowTabBar', this.showTabBarHandler);
|
378 | Taro.eventCenter.off('__taroHideTabBar', this.hideTabBarHandler);
|
379 | Taro.eventCenter.off('__taroSetTabBarStyle', this.setTabBarStyleHandler);
|
380 | Taro.eventCenter.off('__taroSetTabBarItem', this.setTabBarItemHandler);
|
381 | }
|
382 | componentDidLoad() {
|
383 | this.tabbarPos = this.tabbar.nextElementSibling ? 'top' : 'bottom';
|
384 | this.bindEvent();
|
385 | this.routerChangeHandler();
|
386 | }
|
387 | disconnectedCallback() {
|
388 | this.removeEvent();
|
389 | }
|
390 | render() {
|
391 | const { tabbarPos = 'bottom' } = this;
|
392 | const status = this.status;
|
393 | const containerCls = classnames('weui-tabbar', {
|
394 | [`taro-tabbar__border-${this.borderStyle || 'black'}`]: true
|
395 | });
|
396 | const shouldHideTabBar = this.selectedIndex === -1 || status === STATUS_HIDE;
|
397 | const shouldSlideout = status === STATUS_SLIDEOUT;
|
398 | return (h(Host, { class: classnames(basicTabBarClassName, `${basicTabBarClassName}-${tabbarPos}`, {
|
399 | [hideTabBarClassName]: shouldHideTabBar,
|
400 | [hideTabBarWithAnimationClassName]: shouldSlideout
|
401 | }) }, h("div", { class: containerCls, style: {
|
402 | backgroundColor: this.backgroundColor || '',
|
403 | height: 'inherit'
|
404 | } }, this.list.map((item, index) => {
|
405 | const isSelected = this.selectedIndex === index;
|
406 | let textColor;
|
407 | let iconPath;
|
408 | if (isSelected) {
|
409 | textColor = this.selectedColor || '';
|
410 | iconPath = item.selectedIconPath;
|
411 | }
|
412 | else {
|
413 | textColor = this.color || '';
|
414 | iconPath = item.iconPath;
|
415 | }
|
416 | return (h(TabbarItem, { index: index, onSelect: this.switchTab.bind(this), isSelected: isSelected, textColor: textColor, iconPath: iconPath, text: item.text, badgeText: item.badgeText, showRedDot: item.showRedDot }));
|
417 | }))));
|
418 | }
|
419 | get tabbar() { return getElement(this); }
|
420 | };
|
421 | Tabbar.style = indexCss;
|
422 |
|
423 | export { Tabbar as taro_tabbar };
|