150 lines
2.8 KiB
Vue
150 lines
2.8 KiB
Vue
![]() |
<template>
|
||
|
<div v-if="isOpen">
|
||
|
<component
|
||
|
:is="isRouterLink && isOpen ? 'RouterLink' : 'button'"
|
||
|
:to="isRouterLink && isOpen ? route : null"
|
||
|
@click="isOpen ? handleClick : onClick"
|
||
|
:class="['Btn', { 'Btn--hover': isClosedHoverable, 'Btn--open': isOpen }]"
|
||
|
>
|
||
|
<div class="sign">
|
||
|
<svg :class="'icon icon-' + icon">
|
||
|
<use :xlink:href="'#icon-' + icon"></use>
|
||
|
</svg>
|
||
|
</div>
|
||
|
<div class="text">{{ text }}</div>
|
||
|
</component>
|
||
|
</div>
|
||
|
<div v-else>
|
||
|
<component
|
||
|
:is="isRouterLink && isOpen ? 'RouterLink' : 'button'"
|
||
|
:to="isRouterLink && isOpen ? route : null"
|
||
|
@click="isOpen ? handleClick : onClick"
|
||
|
:class="['Btn', { 'Btn--hover': isClosedHoverable, 'Btn--open': isOpen }]"
|
||
|
>
|
||
|
<div class="sign">
|
||
|
<svg :class="'icon icon-' + icon">
|
||
|
<use :xlink:href="'#icon-' + icon"></use>
|
||
|
</svg>
|
||
|
</div>
|
||
|
<div class="text">{{ text }}</div>
|
||
|
</component>
|
||
|
</div>
|
||
|
|
||
|
</template>
|
||
|
|
||
|
<script>
|
||
|
export default {
|
||
|
props: {
|
||
|
icon: {
|
||
|
type: String,
|
||
|
required: true,
|
||
|
},
|
||
|
text: {
|
||
|
type: String,
|
||
|
required: true,
|
||
|
},
|
||
|
route: {
|
||
|
type: [String, Object],
|
||
|
default: null,
|
||
|
},
|
||
|
isRouterLink: {
|
||
|
type: Boolean,
|
||
|
default: false,
|
||
|
},
|
||
|
isOpen: {
|
||
|
type: Boolean,
|
||
|
default: false,
|
||
|
},
|
||
|
enableHover: {
|
||
|
type: Boolean,
|
||
|
default: true,
|
||
|
},
|
||
|
},
|
||
|
computed: {
|
||
|
isClosedHoverable() {
|
||
|
return !this.isOpen && this.enableHover;
|
||
|
},
|
||
|
},
|
||
|
methods: {
|
||
|
handleClick() {
|
||
|
if (this.isRouterLink) {
|
||
|
this.$router.push(this.route);
|
||
|
} else {
|
||
|
this.$emit('click');
|
||
|
}
|
||
|
},
|
||
|
onClick() {
|
||
|
if (!this.isRouterLink || !this.isOpen) {
|
||
|
this.$emit('click');
|
||
|
}
|
||
|
},
|
||
|
},
|
||
|
};
|
||
|
</script>
|
||
|
|
||
|
<style scoped lang="scss">
|
||
|
.Btn {
|
||
|
display: flex;
|
||
|
align-items: center;
|
||
|
justify-content: flex-start;
|
||
|
width: 35px;
|
||
|
height: 35px;
|
||
|
border-radius: calc(45px / 2);
|
||
|
border: none;
|
||
|
cursor: pointer;
|
||
|
position: relative;
|
||
|
overflow: hidden;
|
||
|
transition-duration: 0.3s;
|
||
|
box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.199);
|
||
|
background: #00baba;
|
||
|
}
|
||
|
|
||
|
.sign {
|
||
|
width: 100%;
|
||
|
font-size: 1.5rem;
|
||
|
color: white;
|
||
|
transition-duration: 0.3s;
|
||
|
display: flex;
|
||
|
align-items: center;
|
||
|
justify-content: center;
|
||
|
padding-top: 0em;
|
||
|
svg {
|
||
|
width: 1em;
|
||
|
height: 1em;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
.text {
|
||
|
position: absolute;
|
||
|
right: 0%;
|
||
|
width: 0%;
|
||
|
opacity: 0;
|
||
|
color: white;
|
||
|
font-size: 1rem;
|
||
|
font-weight: 500;
|
||
|
transition-duration: 0.3s;
|
||
|
}
|
||
|
|
||
|
/* Hover and open styles */
|
||
|
.Btn--hover:hover,
|
||
|
.Btn--open {
|
||
|
width: 100px;
|
||
|
transition-duration: 0.3s;
|
||
|
}
|
||
|
|
||
|
.Btn--hover:hover .sign,
|
||
|
.Btn--open .sign {
|
||
|
padding-left: 2.3em;
|
||
|
}
|
||
|
|
||
|
.Btn--hover:hover .text,
|
||
|
.Btn--open .text {
|
||
|
opacity: 1;
|
||
|
width: 70%;
|
||
|
padding-right: 2.6em;
|
||
|
}
|
||
|
|
||
|
.Btn:active {
|
||
|
transform: translate(2px, 2px);
|
||
|
}
|
||
|
</style>
|