framework7-vue
Version:
Build full featured iOS & Android apps using Framework7 & Vue
215 lines • 8.15 kB
JavaScript
import { createElementVNode as _createElementVNode, renderSlot as _renderSlot, resolveComponent as _resolveComponent, withCtx as _withCtx, openBlock as _openBlock, createBlock as _createBlock, createCommentVNode as _createCommentVNode, toDisplayString as _toDisplayString, createTextVNode as _createTextVNode, createElementBlock as _createElementBlock, normalizeClass as _normalizeClass } from "vue";
const _hoisted_1 = {
key: 3,
className: "title-large"
};
const _hoisted_2 = {
className: "title-large-text"
};
function render(_ctx, _cache) {
const _component_f7_nav_left = _resolveComponent("f7-nav-left");
const _component_f7_nav_title = _resolveComponent("f7-nav-title");
const _component_f7_nav_right = _resolveComponent("f7-nav-right");
return _openBlock(), _createElementBlock("div", {
ref: "elRef",
class: _normalizeClass(_ctx.classes)
}, [_cache[0] || (_cache[0] = _createElementVNode("div", {
class: "navbar-bg"
}, null, -1)), _renderSlot(_ctx.$slots, "before-inner"), _createElementVNode("div", {
class: _normalizeClass(_ctx.innerClasses)
}, [_ctx.hasLeft ? (_openBlock(), _createBlock(_component_f7_nav_left, {
key: 0,
"back-link": _ctx.backLink,
"back-link-url": _ctx.backLinkUrl,
"back-link-force": _ctx.backLinkForce,
"back-link-show-text": _ctx.backLinkShowText,
"onBack:click": _ctx.onBackClick
}, {
default: _withCtx(() => [_renderSlot(_ctx.$slots, "nav-left"), _renderSlot(_ctx.$slots, "left")]),
_: 3
}, 8, ["back-link", "back-link-url", "back-link-force", "back-link-show-text", "onBack:click"])) : _createCommentVNode("", true), _ctx.hasTitle ? (_openBlock(), _createBlock(_component_f7_nav_title, {
key: 1,
title: _ctx.title,
subtitle: _ctx.subtitle
}, {
default: _withCtx(() => [_renderSlot(_ctx.$slots, "title")]),
_: 3
}, 8, ["title", "subtitle"])) : _createCommentVNode("", true), _ctx.hasRight ? (_openBlock(), _createBlock(_component_f7_nav_right, {
key: 2
}, {
default: _withCtx(() => [_renderSlot(_ctx.$slots, "nav-right"), _renderSlot(_ctx.$slots, "right")]),
_: 3
})) : _createCommentVNode("", true), _ctx.hasLargeTitle ? (_openBlock(), _createElementBlock("div", _hoisted_1, [_createElementVNode("div", _hoisted_2, [_createTextVNode(_toDisplayString(_ctx.largeTitle) + " ", 1), _renderSlot(_ctx.$slots, "title-large")])])) : _createCommentVNode("", true), _renderSlot(_ctx.$slots, "default")], 2), _renderSlot(_ctx.$slots, "after-inner")], 2);
}
import { computed, ref, onMounted, onBeforeUnmount } from 'vue';
import { classNames } from '../shared/utils.js';
import { colorClasses, colorProps } from '../shared/mixins.js';
import { f7ready, f7 } from '../shared/f7.js';
import { useTheme } from '../shared/use-theme.js';
import f7NavLeft from './nav-left.js';
import f7NavTitle from './nav-title.js';
import f7NavRight from './nav-right.js';
export default {
name: 'f7-navbar',
render,
components: {
f7NavLeft,
f7NavTitle,
f7NavRight
},
props: {
backLink: [Boolean, String],
backLinkUrl: String,
backLinkForce: Boolean,
backLinkShowText: {
type: Boolean,
default: undefined
},
title: String,
subtitle: String,
hidden: Boolean,
outline: {
type: Boolean,
default: true
},
innerClass: String,
innerClassName: String,
large: Boolean,
largeTransparent: Boolean,
transparent: Boolean,
titleLarge: String,
...colorProps
},
emits: ['navbar:hide', 'navbar:show', 'navbar:expand', 'navbar:collapse', 'navbar:transparentshow', 'navbar:transparenthide', 'click:back', 'back:click'],
setup(props, {
emit,
slots
}) {
let routerPositionClass = '';
let largeCollapsed = false;
let transparentVisible = false;
const elRef = ref(null);
const theme = useTheme();
const onHide = navbarEl => {
if (elRef.value !== navbarEl) return;
emit('navbar:hide');
};
const onShow = navbarEl => {
if (elRef.value !== navbarEl) return;
emit('navbar:show');
};
const onExpand = navbarEl => {
if (elRef.value !== navbarEl) return;
largeCollapsed = false;
emit('navbar:expand');
};
const onCollapse = navbarEl => {
if (elRef.value !== navbarEl) return;
largeCollapsed = true;
emit('navbar:collapse');
};
const onNavbarTransparentShow = navbarEl => {
if (elRef.value !== navbarEl) return;
transparentVisible = true;
emit('navbar:transparentshow');
};
const onNavbarTransparentHide = navbarEl => {
if (elRef.value !== navbarEl) return;
transparentVisible = false;
emit('navbar:transparenthide');
};
const onNavbarPosition = (navbarEl, position) => {
if (elRef.value !== navbarEl) return;
routerPositionClass = position ? `navbar-${position}` : '';
};
const hide = animate => {
if (!f7) return;
f7.navbar.hide(elRef.value, animate);
};
const show = animate => {
if (!f7) return;
f7.navbar.show(elRef.value, animate);
};
const size = () => {
if (!f7) return;
f7.navbar.size(elRef.value);
};
const onBackClick = event => {
emit('back:click', event);
emit('click:back', event);
};
onMounted(() => {
if (!elRef.value) return;
f7ready(() => {
f7.navbar.size(elRef.value);
f7.on('navbarShow', onShow);
f7.on('navbarHide', onHide);
f7.on('navbarCollapse', onCollapse);
f7.on('navbarExpand', onExpand);
f7.on('navbarPosition', onNavbarPosition);
f7.on('navbarTransparentShow', onNavbarTransparentShow);
f7.on('navbarTransparentHide', onNavbarTransparentHide);
});
});
onBeforeUnmount(() => {
if (!f7) return;
f7.off('navbarShow', onShow);
f7.off('navbarHide', onHide);
f7.off('navbarCollapse', onCollapse);
f7.off('navbarExpand', onExpand);
f7.off('navbarPosition', onNavbarPosition);
f7.off('navbarTransparentShow', onNavbarTransparentShow);
f7.off('navbarTransparentHide', onNavbarTransparentHide);
});
const addLeftTitleClass = computed(() => theme.value && theme.value.ios && f7 && !f7.params.navbar.iosCenterTitle);
const addCenterTitleClass = computed(() => theme.value && theme.value.md && f7 && f7.params.navbar.mdCenterTitle);
const isLarge = computed(() => props.large || props.largeTransparent);
const isTransparent = computed(() => props.transparent || isLarge.value && props.largeTransparent);
const isTransparentVisible = computed(() => isTransparent.value && transparentVisible);
const classes = computed(() => classNames('navbar', routerPositionClass, {
'navbar-hidden': props.hidden,
'navbar-large': isLarge.value,
'navbar-large-collapsed': isLarge.value && largeCollapsed,
'navbar-transparent': isTransparent.value,
'navbar-transparent-visible': isTransparentVisible.value,
'no-outline': !props.outline
}, colorClasses(props)));
const largeTitle = computed(() => {
let largeTitleText = props.titleLarge;
if (!largeTitleText && props.large && props.title) largeTitleText = props.title;
return largeTitleText;
});
const hasLeft = computed(() => {
return props.backLink || slots['nav-left'] || slots.left;
});
const hasTitle = computed(() => {
return props.title || props.subtitle || slots.title;
});
const hasRight = computed(() => {
return slots['nav-right'] || slots.right;
});
const hasLargeTitle = computed(() => {
return largeTitle.value || slots['title-large'];
});
const innerClasses = computed(() => {
return classNames('navbar-inner', props.innerClass, props.innerClassName, {
'navbar-inner-left-title': addLeftTitleClass.value,
'navbar-inner-centered-title': addCenterTitleClass.value
});
});
return {
elRef,
classes,
innerClasses,
hide,
show,
size,
largeTitle,
hasLeft,
hasTitle,
hasRight,
hasLargeTitle,
onBackClick
};
}
};