mirror of
https://github.com/Spythere/stacjownik.git
synced 2026-05-04 13:58:12 +00:00
Animacja select boxa
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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!";
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user