marktext/src/renderer/components/sideBar/index.vue
冉四夕 4be72ade97
Notification (#337)
* rewrite notice module

* optimization: show some notification when export html or pdf

* optimization: style of open project button

* little bug fix

* style: uniform titlebar hight to remove some style error
2018-06-15 21:30:10 +08:00

222 lines
5.4 KiB
Vue

<template>
<div
v-show="showSideBar"
class="side-bar"
:class="[theme]"
ref="sideBar"
:style="{ 'width': `${finalSideBarWidth}px` }"
>
<div class="left-column">
<ul>
<li
v-for="(icon, index) of sideBarIcons"
:key="index"
@click="handleLeftIconClick(icon.name)"
:class="{ 'active': icon.name === rightColumn }"
>
<svg class="icon" aria-hidden="true">
<use :xlink:href="'#' + icon.icon"></use>
</svg>
</li>
</ul>
<ul class="bottom">
<li
v-for="(icon, index) of sideBarBottomIcons"
:key="index"
@click="handleLeftBottomClick(icon.name)"
>
<svg class="icon" aria-hidden="true">
<use :xlink:href="'#' + icon.icon"></use>
</svg>
</li>
</ul>
</div>
<div class="right-column" v-show="rightColumn">
<tree
:project-tree="projectTree"
:file-list="fileList"
:opened-files="openedFiles"
:tabs="tabs"
v-if="rightColumn === 'files'"
></tree>
<side-bar-search
v-else-if="rightColumn === 'search'"
></side-bar-search>
<toc
v-else-if="rightColumn === 'toc'"
></toc>
</div>
<div class="drag-bar" ref="dragBar"></div>
</div>
</template>
<script>
import { sideBarIcons, sideBarBottomIcons } from './help'
import bus from '../../bus'
import Tree from './tree.vue'
import SideBarSearch from './search.vue'
import Toc from './toc.vue'
import { mapState, mapGetters } from 'vuex'
export default {
data () {
this.sideBarIcons = sideBarIcons
this.sideBarBottomIcons = sideBarBottomIcons
return {
openedFiles: [],
sideBarViewWidth: 280
}
},
components: {
Tree,
SideBarSearch,
Toc
},
computed: {
...mapState({
'theme': state => state.preferences.theme,
'rightColumn': state => state.layout.rightColumn,
'showSideBar': state => state.layout.showSideBar,
'projectTree': state => state.project.projectTree,
'sideBarWidth': state => state.project.sideBarWidth,
'tabs': state => state.editor.tabs
}),
...mapGetters(['fileList']),
finalSideBarWidth () {
const { showSideBar, rightColumn, sideBarViewWidth } = this
let width = sideBarViewWidth
if (rightColumn === '') width = 45
if (!showSideBar) width -= 45
return width
}
},
created () {
this.$nextTick(() => {
const dragBar = this.$refs.dragBar
let startX = 0
let sideBarWidth = +this.sideBarWidth
let startWidth = sideBarWidth
this.sideBarViewWidth = sideBarWidth
const mouseUpHandler = event => {
document.removeEventListener('mousemove', mouseMoveHandler, false)
document.removeEventListener('mouseup', mouseUpHandler, false)
this.$store.dispatch('CHANGE_SIDE_BAR_WIDTH', sideBarWidth)
}
const mouseMoveHandler = event => {
const offset = event.clientX - startX
sideBarWidth = startWidth + offset
this.sideBarViewWidth = sideBarWidth
}
const mouseDownHandler = event => {
startX = event.clientX
startWidth = +this.sideBarWidth
document.addEventListener('mousemove', mouseMoveHandler, false)
document.addEventListener('mouseup', mouseUpHandler, false)
}
dragBar.addEventListener('mousedown', mouseDownHandler, false)
})
},
methods: {
handleLeftIconClick (name) {
if (this.rightColumn === name) {
this.$store.commit('SET_LAYOUT', { rightColumn: '' })
} else {
this.$store.commit('SET_LAYOUT', { rightColumn: name })
this.sideBarViewWidth = +this.sideBarWidth
}
},
handleLeftBottomClick (name) {
if (name === 'twitter') {
bus.$emit('tweetDialog')
}
}
}
}
</script>
<style scoped>
.side-bar {
display: flex;
height: calc(100vh - 25px);
position: relative;
color: var(--secondaryColor);
}
.side-bar.dark {
background: var(--darkBgColor);
}
.left-column {
height: 100%;
width: 45px;
display: flex;
flex-direction: column;
justify-content: space-between;
& > ul {
opacity: 1;
}
}
.left-column ul {
list-style: none;
display: flex;
flex-direction: column;
margin: 0;
padding: 0;
& > li {
width: 45px;
height: 45px;
margin: 0;
padding: 0;
display: flex;
justify-content: space-around;
align-items: center;
cursor: pointer;
&:hover > svg {
color: var(--brandColor);
}
& > svg {
width: 1em;
height: 1em;
opacity: 1;
color: var(--secondaryColor);
}
&.active > svg {
color: var(--activeColor);
}
}
}
.left-column ul.bottom li {
& > svg {
transition: transform .25s ease-in-out;
}
&:hover > svg {
color: #1da1f2;
transform: scale(1.2);
}
}
.side-bar:hover .left-column ul li svg {
opacity: 1;
}
.right-column {
flex: 1;
width: calc(100% - 50px);
}
.drag-bar {
position: absolute;
top: 0;
right: 0;
bottom: 0;
height: 100%;
width: 2px;
cursor: col-resize;
&:hover {
background: var(--secondaryColor);
}
}
</style>