Animacja select boxa

This commit is contained in:
2021-07-05 23:46:49 +02:00
parent 5559fdf83f
commit 5a1f92392a
2 changed files with 74 additions and 41 deletions
+72 -41
View File
@@ -1,55 +1,46 @@
<template> <template>
<div class="select-box"> <div class="select-box">
<div class="select-box_content"> <div class="select-box_content">
<button <button class="selected" @click="toggleBox">
class="selected"
@click="toggleBox"
>
{{ computedSelectedItem.value }} {{ computedSelectedItem.value }}
</button> </button>
<div <transition
class="options" name="expand"
v-if="boxVisible" @enter="expandEnter"
@after-enter="expandAfterEnter"
@leave="expandLeave"
> >
<div <ul class="options" v-show="listOpen" :ref="(el) => (listRef = el)">
class="option" <li class="option" v-for="item in itemList" :key="item.id">
v-for="item in itemList" <label :for="item.id">
:key="item.id" <input
> type="button"
<label :for="item.id"> :id="item.id"
<input name="select-box"
type="button" @click="selectOption(item)"
:id="item.id" />
name="select-box" <span
@click="selectOption(item)" :style="
/> computedSelectedItem.id == item.id ? 'color: gold;' : ''
"
<span :style="computedSelectedItem.id == item.id ? 'color: gold;' : ''"> >
{{ item.value }} {{ item.value }}
</span> </span>
</label> </label>
</div> </li>
</div> </ul>
</transition>
</div> </div>
<div class="arrow"> <div class="arrow">
<img <img :src="listOpen ? ascIcon : descIcon" alt="arrow-icon" />
:src="boxVisible ? ascIcon : descIcon"
alt="arrow-icon"
/>
</div> </div>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { import { computed, defineComponent, Ref, ref } from "@vue/runtime-core";
computed,
defineComponent,
defineEmit,
Ref,
ref,
} from "@vue/runtime-core";
interface Item { interface Item {
id: string | number; id: string | number;
@@ -77,7 +68,9 @@ export default defineComponent({
}), }),
setup(props) { setup(props) {
let boxVisible = ref(false); let listRef: Ref<Element | null> = ref(null);
let listOpen = ref(false);
let selectedItem: Ref<Item> = ref(props.itemList[props.defaultItemIndex]); let selectedItem: Ref<Item> = ref(props.itemList[props.defaultItemIndex]);
const computedSelectedItem = computed(() => { const computedSelectedItem = computed(() => {
@@ -87,23 +80,53 @@ export default defineComponent({
); );
}); });
const computedHeight = computed(() =>
listRef.value ? getComputedStyle(listRef.value).height : 0
);
return { return {
computedSelectedItem, computedSelectedItem,
boxVisible, listOpen,
selectedItem, selectedItem,
listRef,
computedHeight,
}; };
}, },
methods: { methods: {
selectOption(item: Item) { selectOption(item: Item) {
this.selectedItem = item; this.selectedItem = item;
this.boxVisible = false; this.listOpen = false;
this.$emit("selected", item); this.$emit("selected", item);
}, },
toggleBox() { toggleBox() {
this.boxVisible = !this.boxVisible; this.listOpen = !this.listOpen;
},
expandEnter(el: HTMLElement) {
el.style.height = "auto";
const currentHeight = getComputedStyle(el).height;
el.style.height = "0";
setTimeout(() => {
el.style.height = currentHeight;
}, 50);
},
expandAfterEnter(el: HTMLElement) {
el.style.height = "auto";
},
expandLeave(el: HTMLElement) {
el.style.height = getComputedStyle(el).height;
setTimeout(() => {
el.style.height = "0";
}, 50);
}, },
}, },
}); });
@@ -112,6 +135,14 @@ export default defineComponent({
<style lang="scss" scoped> <style lang="scss" scoped>
@import "../../styles/variables.scss"; @import "../../styles/variables.scss";
.expand {
&-enter-active,
&-leave-active {
transition: height 250ms ease-in-out;
overflow: hidden;
}
}
.select-box { .select-box {
position: relative; position: relative;
} }
+2
View File
@@ -222,6 +222,8 @@ export default defineComponent({
} catch (error) { } catch (error) {
historyDataStatus.value.status = DataStatus.Error; historyDataStatus.value.status = DataStatus.Error;
historyDataStatus.value.error = "Ups! Coś poszło nie tak!"; historyDataStatus.value.error = "Ups! Coś poszło nie tak!";
} }
}; };