/
dropdown.vue
175 lines (171 loc) · 4.62 KB
/
dropdown.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
<template>
<div
class="dropdown"
@click.stop="shouldToggleDropdown"
:class="computedClasses"
:style="computedStyles"
>
<div class="dropdown-label-container">
<div class="dropdown-label">
<span class="text">
{{ (config && config.prefix ? config.prefix : "") + " "
}}{{ config && config.placeholder ? config.placeholder : placeholder }}
</span>
<i class="angle-down" :class="{ toggled: isExpanded }"></i>
</div>
</div>
<div v-expand="isExpanded" class="options expand">
<div
v-for="(i, option) in configOptions"
:key="'option-' + i"
class="option"
@click="setCurrentSelectedOption(option);"
>
{{ option.value }}
</div>
</div>
</div>
</template>
<script>
export default {
name: "dropdown",
data() {
return {
isBottomSectionToggled: false,
optionsHeight: 0,
optionHeight: 35,
configOptions: [
{
value: "option 1"
},
{
value: "option 2"
},
{
value: "option 3"
}
],
backgroundColor: "#cde4f5",
backgroundExpandedColor: "#fff",
hoverBackgroundColor: "#0084d4",
disabledBackgroundColor: "#ccc",
disabledTextColor: "#555",
isExpanded: false,
placeholder: "Placeholder",
textColor: "black",
borderRadius: "1.5em",
border: "1px solid gray",
width: 180
};
},
components: {},
props: ["config"],
computed: {
computedStyles: function () {
return [
{"--options-height": this.optionsHeight + "px"},
{"--options-height-neg": "-" + this.optionsHeight + "px"},
{"--option-height": this.optionHeight + "px"},
{"--main-el-border-radius": this.borderRadius},
{"--dropdown-width": this.width + "px"},
{"--dropdown-background-color": this.config.disabled ? this.disabledBackgroundColor : this.backgroundColor},
{"--dropdown-expanded-color": this.backgroundExpandedColor},
{"--dropdown-border": this.border},
{"--dropdown-hover-background-color": this.hoverBackgroundColor},
{"--dropdown-default-text-color": this.config.disabled ? this.disabledTextColor : this.textColor}
];
},
computedClasses: function() {
return {
'expanded': this.isExpanded,
'disabled': this.config.disabled
}
}
},
directives: {
expand: {
inserted: function (el, binding) {
if (binding.value !== null) {
function calcHeight() {
const currentState = el.getAttribute("aria-expanded");
el.classList.add("u-no-transition");
el.removeAttribute("aria-expanded");
el.style.height = null;
el.style.height = el.clientHeight + "px";
el.setAttribute("aria-expanded", currentState);
setTimeout(function () {
el.classList.remove("u-no-transition");
});
}
el.classList.add("expand");
el.setAttribute("aria-expanded", binding.value ? "true" : "false");
calcHeight();
window.addEventListener("resize", calcHeight);
}
},
update: function (el, binding) {
if (el.style.height && binding.value !== null) {
el.setAttribute("aria-expanded", binding.value ? "true" : "false");
}
}
}
},
methods: {
setCurrentSelectedOption(option) {
this.$emit("setSelectedOption", option);
},
setConfigData() {
if (this.config) {
this.configOptions = this.config.options;
this.width = this.config.width;
this.placeholder = this.config.placeholder;
if (this.config.backgroundColor) {
this.backgroundColor = this.config.backgroundColor;
}
if (this.config.backgroundExpandedColor) {
this.backgroundExpandedColor = this.config.backgroundExpandedColor;
}
if (this.config.border) {
this.border = this.config.border;
}
if (this.config.hoverBackgroundColor) {
this.hoverBackgroundColor = this.config.hoverBackgroundColor;
}
if (this.config.textColor) {
this.textColor = this.config.textColor;
}
if (this.config.borderRadius) {
this.borderRadius = this.config.borderRadius;
}
}
},
setOptionsHeight() {
this.optionsHeight = this.optionHeight * this.configOptions.length;
},
documentClicked() {
if (this.isExpanded) {
this.isExpanded = false
}
},
shouldToggleDropdown() {
if (!this.config.disabled) {
this.isExpanded = !this.isExpanded;
}
},
},
created() {
document.addEventListener('click', this.documentClicked);
this.setConfigData();
this.setOptionsHeight();
},
beforeUdate() {
// this.setOptionsHeight();
},
destroyed() {
document.removeEventListener('click', this.documentClicked);
}
};
</script>
<style lang="scss" scoped>
@import "./dropdown";
</style>