v2 first commit

This commit is contained in:
denisdulici
2019-11-16 10:21:14 +03:00
parent 5b23e9c2c4
commit 6d50fa8442
3075 changed files with 3451681 additions and 65594 deletions

View File

@ -0,0 +1,123 @@
<template>
<div class="sidenav navbar navbar-vertical fixed-left navbar-expand-xs navbar-light bg-white"
@mouseenter="$sidebar.onMouseEnter()"
@mouseleave="$sidebar.onMouseLeave()"
:data="backgroundColor">
<div class="scrollbar-inner" ref="sidebarScrollArea">
<div class="sidenav-header d-flex align-items-center">
<a class="navbar-brand" href="#">
<img :src="logo" class="navbar-brand-img" alt="Sidebar logo">
</a>
<div class="ml-auto">
<!-- Sidenav toggler -->
<div class="sidenav-toggler d-none d-xl-block"
:class="{'active': !$sidebar.isMinimized }"
@click="minimizeSidebar">
<div class="sidenav-toggler-inner">
<i class="sidenav-toggler-line"></i>
<i class="sidenav-toggler-line"></i>
<i class="sidenav-toggler-line"></i>
</div>
</div>
</div>
</div>
<slot></slot>
<div class="navbar-inner">
<ul class="navbar-nav">
<slot name="links">
<sidebar-item
v-for="(link, index) in sidebarLinks"
:key="link.name + index"
:link="link"
>
<sidebar-item
v-for="(subLink, index) in link.children"
:key="subLink.name + index"
:link="subLink"
>
</sidebar-item>
</sidebar-item>
</slot>
</ul>
<slot name="links-after"></slot>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'sidebar',
props: {
title: {
type: String,
default: 'Creative Tim',
description: 'Sidebar title'
},
shortTitle: {
type: String,
default: 'CT',
description: 'Sidebar short title'
},
logo: {
type: String,
default: 'https://demos.creative-tim.com/vue-argon-dashboard-pro/img/brand/green.png',
description: 'Sidebar app logo'
},
backgroundColor: {
type: String,
default: 'vue',
validator: value => {
let acceptedValues = [
'',
'vue',
'blue',
'green',
'orange',
'red',
'primary'
];
return acceptedValues.indexOf(value) !== -1;
},
description:
'Sidebar background color (vue|blue|green|orange|red|primary)'
},
sidebarLinks: {
type: Array,
default: () => [],
description:
"List of sidebar links as an array if you don't want to use components for these."
},
autoClose: {
type: Boolean,
default: true,
description:
'Whether sidebar should autoclose on mobile when clicking an item'
}
},
provide() {
return {
autoClose: this.autoClose
};
},
methods: {
minimizeSidebar() {
if (this.$sidebar) {
this.$sidebar.toggleMinimize();
}
}
},
beforeDestroy() {
if (this.$sidebar.showSidebar) {
this.$sidebar.showSidebar = false;
}
}
};
</script>
<style>
@media (min-width: 992px) {
.navbar-search-form-mobile,
.nav-mobile-menu {
display: none;
}
}
</style>

View File

@ -0,0 +1,198 @@
<template>
<component
:is="baseComponent"
:to="link.path ? link.path : '/'"
class="nav-item"
:class="{ active: isActive }"
tag="li"
>
<a
v-if="isMenu"
class="sidebar-menu-item nav-link"
:class="{ active: isActive }"
:aria-expanded="!collapsed"
data-toggle="collapse"
@click.prevent="collapseMenu"
>
<template v-if="addLink">
<span class="nav-link-text">
{{ link.name }} <b class="caret"></b>
</span>
</template>
<template v-else>
<i :class="link.icon"></i>
<span class="nav-link-text">{{ link.name }} <b class="caret"></b></span>
</template>
</a>
<collapse-transition>
<div
v-if="$slots.default || this.isMenu"
v-show="!collapsed"
class="collapse show"
>
<ul class="nav nav-sm flex-column">
<slot></slot>
</ul>
</div>
</collapse-transition>
<slot
name="title"
v-if="children.length === 0 && !$slots.default && link.path"
>
<component
:to="link.path"
@click.native="linkClick"
:is="elementType(link, false)"
class="nav-link"
:class="{ active: link.active }"
:target="link.target"
:href="link.path"
>
<template v-if="addLink">
<span class="nav-link-text">{{ link.name }}</span>
</template>
<template v-else>
<i :class="link.icon"></i>
<span class="nav-link-text">{{ link.name }}</span>
</template>
</component>
</slot>
</component>
</template>
<script>
import { CollapseTransition } from 'vue2-transitions';
export default {
name: 'sidebar-item',
components: {
CollapseTransition
},
props: {
menu: {
type: Boolean,
default: false,
description:
"Whether the item is a menu. Most of the item it's not used and should be used only if you want to override the default behavior."
},
link: {
type: Object,
default: () => {
return {
name: '',
path: '',
children: []
};
},
description:
'Sidebar link. Can contain name, path, icon and other attributes. See examples for more info'
}
},
provide() {
return {
addLink: this.addChild,
removeLink: this.removeChild
};
},
inject: {
addLink: { default: null },
removeLink: { default: null },
autoClose: {
default: true
}
},
data() {
return {
children: [],
collapsed: true
};
},
computed: {
baseComponent() {
return this.isMenu || this.link.isRoute ? 'li' : 'router-link';
},
linkPrefix() {
if (this.link.name) {
let words = this.link.name.split(' ');
return words.map(word => word.substring(0, 1)).join('');
}
},
isMenu() {
return this.children.length > 0 || this.menu === true;
},
isActive() {
if (this.$route && this.$route.path) {
let matchingRoute = this.children.find(c =>
this.$route.path.startsWith(c.link.path)
);
if (matchingRoute !== undefined) {
return true;
}
}
return false;
}
},
methods: {
addChild(item) {
const index = this.$slots.default.indexOf(item.$vnode);
this.children.splice(index, 0, item);
},
removeChild(item) {
const tabs = this.children;
const index = tabs.indexOf(item);
tabs.splice(index, 1);
},
elementType(link, isParent = true) {
if (link.isRoute === false) {
return isParent ? 'li' : 'a';
} else {
return 'router-link';
}
},
linkAbbreviation(name) {
const matches = name.match(/\b(\w)/g);
return matches.join('');
},
linkClick() {
if (
this.autoClose &&
this.$sidebar &&
this.$sidebar.showSidebar === true
) {
this.$sidebar.displaySidebar(false);
}
},
collapseMenu() {
this.collapsed = !this.collapsed;
},
collapseSubMenu(link) {
link.collapsed = !link.collapsed;
}
},
mounted() {
if (this.addLink) {
this.addLink(this);
}
if (this.link.collapsed !== undefined) {
this.collapsed = this.link.collapsed;
}
if (this.isActive && this.isMenu) {
this.collapsed = false;
}
},
destroyed() {
if (this.$el && this.$el.parentNode) {
this.$el.parentNode.removeChild(this.$el);
}
if (this.removeLink) {
this.removeLink(this);
}
}
};
</script>
<style>
.sidebar-menu-item {
cursor: pointer;
}
</style>

View File

@ -0,0 +1,70 @@
import Sidebar from './SideBar.vue';
import SidebarItem from './SidebarItem.vue';
const SidebarStore = {
showSidebar: true,
sidebarLinks: [],
isMinimized: false,
breakpoint: 1200,
displaySidebar(value) {
if (window.innerWidth > this.breakpoint) {
return;
}
this.showSidebar = value;
let docClasses = document.body.classList
if (value) {
docClasses.add('g-sidenav-pinned')
docClasses.add('g-sidenav-show')
docClasses.remove('g-sidenav-hidden')
} else {
docClasses.add('g-sidenav-hidden')
docClasses.remove('g-sidenav-pinned')
}
},
toggleMinimize() {
this.isMinimized = !this.isMinimized;
let docClasses = document.body.classList
if (this.isMinimized) {
docClasses.add('g-sidenav-hidden')
docClasses.remove('g-sidenav-pinned')
} else {
docClasses.add('g-sidenav-pinned')
docClasses.remove('g-sidenav-hidden')
}
},
onMouseEnter() {
if (this.isMinimized) {
document.body.classList.add('g-sidenav-show')
document.body.classList.remove('g-sidenav-hidden')
}
},
onMouseLeave() {
if (this.isMinimized) {
let docClasses = document.body.classList
docClasses.remove('g-sidenav-show')
docClasses.add('g-sidenav-hide')
setTimeout(() => {
docClasses.remove('g-sidenav-hide')
docClasses.add('g-sidenav-hidden')
}, 300)
}
}
};
const SidebarPlugin = {
install(Vue, options) {
if (options && options.sidebarLinks) {
SidebarStore.sidebarLinks = options.sidebarLinks;
}
let app = new Vue({
data: {
sidebarStore: SidebarStore
}
});
Vue.prototype.$sidebar = app.sidebarStore;
Vue.component('side-bar', Sidebar);
Vue.component('sidebar-item', SidebarItem);
}
};
export default SidebarPlugin;