Skip to content

Instantly share code, notes, and snippets.

@iErik
Created August 15, 2018 19:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iErik/3ebd59a0b08f7c28cc90710201849a6c to your computer and use it in GitHub Desktop.
Save iErik/3ebd59a0b08f7c28cc90710201849a6c to your computer and use it in GitHub Desktop.
<template>
<div class="c-multiselect" :class="generatedClass">
<label
v-if="formLabel"
class="label">
<span>
{{ formLabel }}<span v-if="required" class="required">*</span>
</span>
</label>
<transition name="c-multiselect-feedback">
<span
v-if="feedbackShow && feedbackMessage"
class="feedback">
<c-icon v-if="validationIcon" :icon="validationIcon" size="15" class="icon" />
{{ feedbackMessage }}
</span>
</transition>
<div class="inner">
<c-icon v-if="icon" :icon="icon" class="icon" width="20px" height="20px" />
<multiselect
v-on="$listeners"
v-bind="attrs"
open-direction="bottom"
:placeholder="placeholder"
:select-label="selectLabel"
:selected-label="selectedLabel"
:deselect-label="deselectLabel">
<template slot="noResult">{{ noResultMessage }}</template>
<template slot="caret" slot-scope="props">
<div>
<div @mousedown.prevent.stop="props.toggle()" class="multiselect__select">
<c-icon size="15" class="icon" icon="chevron-down" />
</div>
</div>
</template>
<template slot="maxElements">
<div class="option-warning">
<c-icon :icon="validationIcon" size="15" class="icon" />
Máximo de {{ max }} opções selecionadas.
</div>
</template>
</multiselect>
</div>
</div>
</template>
<script>
import Multiselect from 'vue-multiselect'
import Scroll from '@/modules/directives/Scroll'
import CIcon from '@/components/CComponents/CIcon'
export default {
components: { Multiselect, CIcon },
directives: { Scroll },
props: {
validationIcon: {
type: String,
default: 'warning-circle'
},
feedbackType: {
type: String,
default: 'error'
},
feedbackMessage: {
type: String,
default: ''
},
feedbackShow: {
type: Boolean,
default: false
},
noResultMessage: {
type: String,
default: 'Não foram encontradas opções. Considere alterar o filtro.'
},
placeholder: {
type: String,
default: 'Selecione'
},
selectLabel: {
type: String,
default: 'Pressione enter para selecionar'
},
selectedLabel: {
type: String,
default: 'Selecionado'
},
deselectLabel: {
type: String,
default: 'Selecionado'
},
formLabel: {
type: String,
default: ''
},
icon: {
type: String,
default: ''
},
required: {
type: Boolean,
default: false
},
max: [Number, String]
},
computed: {
generatedClass () {
return {
'-success': this.feedbackType === 'success',
'-error': this.feedbackType === 'error',
'-show-feedback': this.feedbackShow,
'-has-icon': this.icon,
}
},
attrs () {
return { ...this.$attrs, ...(this.max ? { max: this.max } : { }) }
}
}
}
</script>
<style lang="scss">
@import '~@/styles/reference';
@import '~vue-multiselect/dist/vue-multiselect.min';
$c-select-font-size: 13px !default;
$c-select-feedback-font-size: 13px !default;
$c-select-label-font-size: 10px !default;
$c-select-font-family: $c-font-family-base !default;
$c-select-highlight-background: #f3f4f6 !default;
$c-select-active-background: $c-color-primary !default;
$c-select-background-color: #FFFFFF !default;
$c-select-border-color: #E9EAEE !default;
$c-select-active-border-color: var(--color-secondary) !important;
$c-select-disabled-background-color: #eaedef !default;
$c-select-disabled-color: #bdc0d1 !default;
$c-select-color: $title-color !default;
$c-select-active-font-color: $title-color !default;
$c-select-highlight-font-color: $title-color !default;
$c-select-label-color: #8c92b2 !default;
$c-select-success-border-color: var(--color-secondary) !important;
$c-select-success-color: var(--color-secondary) !important;
$c-select-error-border-color: #ff7987 !default;
$c-select-error-color: #ff7986 !default;
.c-multiselect {
position: relative;
& > .label {
color: $title-color;
text-transform: uppercase;
font-size: 12px;
line-height: 16px;
margin-bottom: 9px;
& > span {
display: flex;
}
}
& > .label .required {
color: $title-color;
display: inline-block;
margin-left: 3.5px;
}
& > .feedback {
display: flex;
align-items: center;
font-size: $c-select-feedback-font-size;
position: absolute;
bottom: 3px;
left: 0;
right: 0;
line-height: 1;
z-index: 1;
& > .icon { margin-right: 5px; }
}
&.-show-feedback {
padding-bottom: outer-base();
}
& .multiselect__tag {
background-color: #E0E1E6 !important;
color: $title-color !important;
font-weight: 600 !important;
font-size: 13px !important;
}
&.-show-feedback.-success {
& .multiselect .multiselect__tags {
border-color: $c-select-success-border-color;
}
& > .feedback {
color: $c-select-success-color;
& > .icon { fill: $c-select-success-color; }
}
}
&.-show-feedback.-error {
& .multiselect .multiselect__tags {
border-color: $c-select-error-border-color;
}
& > .feedback {
color: $c-select-error-color;
& > .icon { fill: $c-select-error-color; }
}
}
&.-has-icon > .inner {
position: relative;
& > .icon {
position: absolute;
top: 50%;
left: 15px;
transform: translateY(-50%);
z-index: 2;
}
.multiselect__single {
text-indent: 30px;
padding-top: 2px;
color: rgba($base-color, 0.3);
}
}
.multiselect {
z-index: 1;
&,
&__input,
&__single {
font-size: $c-select-font-size;
font-family: $c-select-font-family;
color: $c-select-color;
}
&__input,
&__single {
&::placeholder { color: rgba($base-color, 0.3); }
}
&__select {
height: 2.5625rem;
&::before {
border-top-color: gray;
color: $text-color;
}
}
&__tags {
border-color: $c-select-border-color;
}
&__tags,
&__input {
background-color: $c-select-background-color;
}
&__content-wrapper {
margin-top: .3125rem;
border-radius: 8px;
max-height: 240px !important;
}
&__option {
&.multiselect__option > .option-warning {
display: flex;
color: red;
& > .icon {
fill: red;
margin-right: 5px;
}
}
&.multiselect__option--selected,
&.multiselect__option--selected::after {
background-color: unset;
color: unset ;
}
&--highlight,
&--highlight::after {
background-color: $c-select-highlight-background !important;
color: $c-select-highlight-font-color !important;
}
&--selected,
&--selected::after {
background-color: $c-select-active-background;
color: $c-select-active-font-color;
}
}
& .multiselect__tags {
transition: border 0.3s ease-in-out;
will-change: border;;
&:focus {
outline: none;
}
}
&--active {
z-index: 100;
&::after { opacity: 1; }
& .multiselect__tags {
border-radius: 3px;
transition: box-shadow 0.3s ease;
box-shadow: 0 0 0 3px $c-select-active-border-color;
border-color: transparent;
}
}
&--disabled {
opacity: 1 !important;
}
&--disabled .multiselect__tags,
&--disabled .multiselect__input {
color: $c-select-disabled-color;
background-color: $c-select-disabled-background-color;
border-color: $c-select-disabled-background-color;
border-radius: 3px;
pointer-events: all;
&:hover { cursor: default; }
&::placeholder { color: $c-select-disabled-color; }
}
&__tag {
background-color: $c-color-primary;
&-icon:hover { background-color: $c-color-primary; }
&-icon::after { color: $c-select-active-font-color ; }
}
}
&.-show-feedback.-success .multiselect--active {
& .multiselect__tags {
box-shadow: 0 0 0 3px $c-select-success-border-color;
}
}
&.-show-feedback.-error .multiselect--active {
& .multiselect__tags {
box-shadow: 0 0 0 3px $c-select-error-border-color;
}
}
.multiselect__single { color: rgba($base-color, 0.3) !important; }
}
.c-multiselect-feedback-enter-active,
.c-multiselect-feedback-leave-active {
transition: all 0.3s ease-out;
}
.c-multiselect-feedback-enter,
.c-multiselect-feedback-leave-to {
opacity: 0;
transform: translateY(-10px);
}
.multiselect__select {
svg {
margin-top: 8px;
}
&:before {
display: none;
}
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment