mirror of
https://github.com/Spythere/stacjownik.git
synced 2026-05-03 21:38:13 +00:00
SelectBox: animacja zwijania/rozwijania
This commit is contained in:
@@ -5,15 +5,15 @@
|
|||||||
{{ computedSelectedItem.value }}
|
{{ computedSelectedItem.value }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<transition
|
<ul class="options" :ref="(el) => (listRef = el)">
|
||||||
name="expand"
|
<li class="option" v-for="(item, i) in itemList" :key="item.id">
|
||||||
@enter="expandEnter"
|
<transition
|
||||||
@after-enter="expandAfterEnter"
|
name="unfold"
|
||||||
@leave="expandLeave"
|
:style="`
|
||||||
>
|
--delay-in: ${i * 55}ms;
|
||||||
<ul class="options" v-show="listOpen" :ref="(el) => (listRef = el)">
|
--delay-out: ${(itemList.length - 1 - i) * 55}ms`"
|
||||||
<li class="option" v-for="item in itemList" :key="item.id">
|
>
|
||||||
<label :for="item.id">
|
<label :for="item.id" v-if="listOpen">
|
||||||
<input
|
<input
|
||||||
type="button"
|
type="button"
|
||||||
:id="item.id"
|
:id="item.id"
|
||||||
@@ -28,9 +28,9 @@
|
|||||||
{{ item.value }}
|
{{ item.value }}
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
</li>
|
</transition>
|
||||||
</ul>
|
</li>
|
||||||
</transition>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="arrow">
|
<div class="arrow">
|
||||||
@@ -83,20 +83,12 @@ export default defineComponent({
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const computedHeight = computed(() =>
|
|
||||||
listRef.value ? getComputedStyle(listRef.value).height : 0
|
|
||||||
);
|
|
||||||
|
|
||||||
const buttonFocused = computed(() => document.activeElement);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
computedSelectedItem,
|
computedSelectedItem,
|
||||||
listOpen,
|
listOpen,
|
||||||
selectedItem,
|
selectedItem,
|
||||||
listRef,
|
listRef,
|
||||||
buttonRef,
|
buttonRef,
|
||||||
computedHeight,
|
|
||||||
buttonFocused,
|
|
||||||
activeEl,
|
activeEl,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -109,40 +101,16 @@ export default defineComponent({
|
|||||||
this.$emit("selected", item);
|
this.$emit("selected", item);
|
||||||
},
|
},
|
||||||
|
|
||||||
toggleBox() {
|
toggleBox(e: Event) {
|
||||||
this.listOpen = !this.listOpen;
|
this.listOpen = !this.listOpen;
|
||||||
|
|
||||||
|
if (!this.listOpen) (e.target as HTMLButtonElement).blur();
|
||||||
},
|
},
|
||||||
|
|
||||||
clickedOutside() {
|
clickedOutside() {
|
||||||
this.listOpen = false;
|
this.listOpen = false;
|
||||||
this.buttonRef?.blur();
|
this.buttonRef?.blur();
|
||||||
},
|
},
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
getComputedStyle(el);
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
el.style.height = "0";
|
|
||||||
}, 50);
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@@ -150,11 +118,24 @@ export default defineComponent({
|
|||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "../../styles/variables.scss";
|
@import "../../styles/variables.scss";
|
||||||
|
|
||||||
.expand {
|
.unfold {
|
||||||
|
&-enter-from,
|
||||||
|
&-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-10px) scale(0.85);
|
||||||
|
}
|
||||||
|
|
||||||
&-enter-active,
|
&-enter-active,
|
||||||
&-leave-active {
|
&-leave-active {
|
||||||
transition: height 150ms ease-out;
|
transition: all 110ms ease-out;
|
||||||
overflow: hidden;
|
}
|
||||||
|
|
||||||
|
&-enter-active {
|
||||||
|
transition-delay: var(--delay-in);
|
||||||
|
}
|
||||||
|
|
||||||
|
&-leave-active {
|
||||||
|
transition-delay: var(--delay-out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,31 +158,6 @@ export default defineComponent({
|
|||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.select-box_content {
|
|
||||||
position: relative;
|
|
||||||
margin: 0 auto;
|
|
||||||
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
min-width: 10em;
|
|
||||||
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.options {
|
|
||||||
position: absolute;
|
|
||||||
top: 100%;
|
|
||||||
left: 0;
|
|
||||||
|
|
||||||
height: auto;
|
|
||||||
|
|
||||||
z-index: 10;
|
|
||||||
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
margin-top: 0.25em;
|
|
||||||
}
|
|
||||||
|
|
||||||
button.selected {
|
button.selected {
|
||||||
background: #333;
|
background: #333;
|
||||||
color: white;
|
color: white;
|
||||||
@@ -224,37 +180,68 @@ button.selected {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
input {
|
.select-box_content {
|
||||||
position: absolute;
|
position: relative;
|
||||||
top: 0;
|
margin: 0 auto;
|
||||||
left: 0;
|
|
||||||
|
|
||||||
-webkit-appearance: none;
|
height: 100%;
|
||||||
-moz-appearance: none;
|
|
||||||
appearance: none;
|
|
||||||
border: none;
|
|
||||||
|
|
||||||
&:focus + span {
|
min-width: 10em;
|
||||||
color: $accentCol;
|
|
||||||
font-weight: bold;
|
text-align: center;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
label {
|
ul.options {
|
||||||
position: relative;
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
left: 0;
|
||||||
|
|
||||||
display: inline-block;
|
height: auto;
|
||||||
background-color: hsla(0, 0%, 0%, 0.85);
|
|
||||||
|
|
||||||
&:hover,
|
z-index: 10;
|
||||||
&:focus {
|
|
||||||
background-color: hsla(0, 0%, 20%, 0.85);
|
|
||||||
}
|
|
||||||
|
|
||||||
padding: 0.75em 0;
|
|
||||||
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
cursor: pointer;
|
margin-top: 0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
li.option {
|
||||||
|
input {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
|
||||||
|
-webkit-appearance: none;
|
||||||
|
-moz-appearance: none;
|
||||||
|
appearance: none;
|
||||||
|
border: none;
|
||||||
|
|
||||||
|
&:focus + span {
|
||||||
|
color: $accentCol;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child label {
|
||||||
|
border-radius: 0 0 1em 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
display: inline-block;
|
||||||
|
background-color: hsla(0, 0%, 15%, 0.95);
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
background-color: hsla(0, 0%, 20%, 0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
padding: 0.75em 0;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
Reference in New Issue
Block a user