Skip to content

Instantly share code, notes, and snippets.

@arkadylukashov
Created August 5, 2019 11:44
Show Gist options
  • Save arkadylukashov/bea5810e4dbbba18be1a2a027b88211c to your computer and use it in GitHub Desktop.
Save arkadylukashov/bea5810e4dbbba18be1a2a027b88211c to your computer and use it in GitHub Desktop.
<template>
<div class="filter" @click="toggleFilter" :class="{'is-active': isShowFilter}">
<div class="filter__title" :class="{'has-filter': hasFilter}">
<IconFilter class="filter__icon" />
<span class="filter__text">Filter <span>by</span></span>
</div>
<ul class="filter__list">
<li class="filter__item"
v-for="(filter, i) in list"
:key="`filter.${i}`"
:class="[{'is-active': isActive(filter.type)}, `type-${filter.type}`]"
>
<template v-if="filter.type == 'topics'">
<IconGrid class="filter__subicon" />
</template>
<template v-if="filter.type == 'dates'">
<IconDate class="filter__subicon" />
</template>
<template v-if="filter.type == 'upvotes'">
<IconUpvote class="filter__subicon" />
</template>
<template v-if="filter.type == 'badges'">
<IconStar class="filter__subicon" />
</template>
{{ filter.title }}
</li>
</ul>
</div>
</template>
<script>
import { mapState, mapGetters, mapActions } from 'vuex'
import { IconFilter, IconGrid, IconDate, IconUpvote, IconStar } from "~/components/Icons"
export default {
components: {
IconFilter, IconGrid, IconDate, IconUpvote, IconStar
},
data() {
return {
list: [
{
type: 'topics',
title: 'Topics',
},
{
type: 'dates',
title: 'Dates',
},
{
type: 'upvotes',
title: 'Upvotes',
},
{
type: 'badges',
title: 'Badges',
},
]
}
},
computed: {
...mapState([
'isShowFilter',
'isShowHistory'
]),
...mapGetters({
filterTopics: 'filter/topics',
filterDates: 'filter/dates',
filterUpvotes: 'filter/upvotes',
filterBadges: 'filter/badges',
}),
hasFilter() {
return !!this.filterTopics || !!this.filterDates || !!this.filterUpvotes || !!this.filterBadges
}
},
methods: {
...mapActions([
'toggleFilter'
]),
isActive(type) {
switch(type) {
case 'topics':
return this.filterTopics != null
break
case 'dates':
return this.filterDates != null
break
case 'upvotes':
return this.filterUpvotes != null
break
case 'badges':
return this.filterBadges != null
break
default:
return false
break
}
}
}
}
</script>
<style lang="scss" scoped>
.filter {
display: flex;
flex-direction: row;
align-items: center;
padding: 15px 15px 15px 25px;
margin: -15px;
border-radius: 5px;
transition: all ease 0.3s;
opacity: 0.7;
background: transparent;
user-select: none;
&:hover {
opacity: 1;
cursor: pointer;
}
&.is-active {
opacity: 1;
}
@include media(mobile) {
padding: 10px;
margin: -10px;
opacity: 1;
}
}
.filter__title {
color: #667D96;
font-size: 15px;
text-transform: uppercase;
font-weight: 500;
letter-spacing: 1.8px;
display: flex;
align-items: center;
position: relative;
@include theme(red, green, blue) {
color: rgba(#fff, 0.4);
}
@include media(tablet-portrait) {
&.has-filter::after {
content: "";
width: 7px;
height: 7px;
background: $rose-color;
position: absolute;
border-radius: 100px;
left: 9px;
top: -7px;
border: 4px solid #0c2134;
@include media(mobile) {
left: 12px;
}
@include theme(light) {
border-color: #f5f7f9;
}
@include theme(red) {
border-color: #db6c5f;
background: #fff;
}
@include theme(green) {
border-color: #3cb2de;
background: #fff;
}
@include theme(blue) {
border-color: #4ac1e8;
background: #fff;
}
}
}
}
.filter__icon {
margin-right: 10px;
margin-top: -2px;
@include media(mobile) {
margin-right: 0;
margin-top: 0;
width: 21px;
height: 21px;
opacity: 0.7;
}
}
.filter__text {
@media screen and (max-width: 560px) {
display: none;
}
span {
@include media(tablet-portrait) {
display: none;
}
}
}
.filter__list {
display: flex;
flex-direction: row;
align-items: center;
@include media(tablet-portrait) {
display: none;
}
}
.filter__item {
margin-left: 40px;
padding: 10px 0;
transition: all ease 0.3s;
border-radius: 3px;
text-transform: uppercase;
font-size: 12px;
line-height: 12px;
text-transform: uppercase;
letter-spacing: 1px;
color: rgba(#667D96, 0.35);
font-weight: 500;
position: relative;
display: flex;
align-items: center;
@include theme(red, green, blue) {
color: rgba(#fff, 0.3);
}
@media screen and (min-width: 800px) and (max-width: 950px) {
margin-left: 25px;
}
&::after {
content: "";
opacity: 0;
width: 5px;
height: 5px;
background: $rose-color;
transition: all ease 0.3s;
position: absolute;
border-radius: 100px;
right: -7px;
top: 7px;
@include theme(red, green, blue) {
background: #fff;
}
}
&.is-active {
color: #667D96;
@include theme(red, green, blue) {
color: rgba(#fff, 0.9);
}
&::after {
opacity: 1;
}
}
}
.filter__subicon {
margin-top: -1px;
margin-right: 6px;
.type-badges & {
margin-top: -3px;
}
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment