Merge branch 'feat/advanced-dropdown-list' of https://github.com/toriphes/antares into pr/toriphes/245

This commit is contained in:
Fabio Di Stasio 2022-05-23 16:19:35 +02:00
commit 3991382153
2 changed files with 38 additions and 22 deletions

View File

@ -32,11 +32,9 @@
> >
<span v-if="searchable && !isOpen || !searchable">{{ currentOptionLabel }}</span> <span v-if="searchable && !isOpen || !searchable">{{ currentOptionLabel }}</span>
</div> </div>
<Teleport <Transition :name="animation">
v-if="isOpen"
:to="dropdownContainer"
>
<div <div
v-if="isOpen"
ref="optionList" ref="optionList"
:class="`select__list-wrapper ${dropdownClass ? dropdownClass : '' }`" :class="`select__list-wrapper ${dropdownClass ? dropdownClass : '' }`"
> >
@ -65,13 +63,12 @@
</li> </li>
</ul> </ul>
</div> </div>
</Teleport> </Transition>
</div> </div>
</template> </template>
<script> <script>
import { defineComponent, computed, ref, watch, nextTick, onMounted, onUnmounted } from 'vue'; import { defineComponent, computed, ref, watch, nextTick, onMounted, onUnmounted } from 'vue';
import { option } from 'yargs';
export default defineComponent({ export default defineComponent({
name: 'BaseSelect', name: 'BaseSelect',
@ -119,9 +116,9 @@ export default defineComponent({
type: Boolean, type: Boolean,
default: true default: true
}, },
dropdownContainer: { animation: {
type: String, type: String,
default: '#window-content' default: 'fade-slide-down'
}, },
dropdownOffsets: { dropdownOffsets: {
type: Object, type: Object,
@ -277,22 +274,20 @@ export default defineComponent({
}; };
const adjustListPosition = () => { const adjustListPosition = () => {
setTimeout(() => { const element = el.value;
const element = el.value; let { left, top } = element.getBoundingClientRect();
let { left, top } = element.getBoundingClientRect(); const { left: offsetLeft = 0, top: offsetTop = 0 } = props.dropdownOffsets;
const { left: offsetLeft = 0, top: offsetTop = 0 } = props.dropdownOffsets; top = top + element.clientHeight + offsetTop;
top = top + element.clientHeight + offsetTop; const openBottom = top >= 0 && top + optionList.value.clientHeight <= window.innerHeight;
const openBottom = top >= 0 && top + optionList.value.clientHeight <= window.innerHeight;
if (!openBottom) { if (!openBottom) {
top -= (offsetTop * 2 + element.clientHeight); top -= (offsetTop * 2 + element.clientHeight);
optionList.value.style.transform = 'translate(0, -100%)'; optionList.value.style.transform = 'translate(0, -100%)';
} }
optionList.value.style.left = `${left + offsetLeft}px`; optionList.value.style.left = `${left + offsetLeft}px`;
optionList.value.style.top = `${top}px`; optionList.value.style.top = `${top}px`;
optionList.value.style.minWidth = `${element.clientWidth}px`; optionList.value.style.minWidth = `${element.clientWidth}px`;
}, 100);
}; };
const keyArrows = (direction) => { const keyArrows = (direction) => {
@ -330,6 +325,14 @@ export default defineComponent({
onMounted(() => { onMounted(() => {
window.addEventListener('resize', adjustListPosition); window.addEventListener('resize', adjustListPosition);
nextTick(() => {
// fix position when the component is created and opened at the same time
if (isOpen.value) {
setTimeout(() => {
adjustListPosition();
}, 50);
}
});
}); });
onUnmounted(() => { onUnmounted(() => {
window.removeEventListener('resize', adjustListPosition); window.removeEventListener('resize', adjustListPosition);

View File

@ -1,3 +1,16 @@
.fade-slide-down-enter-active,
.fade-slide-down-leave-active {
transition: opacity 0.15s ease, transform 0.15s ease;
opacity: 1;
transform: translateY(0);
}
.fade-slide-down-enter-from,
.fade-slide-down-leave-to {
opacity: 0;
transform: translateY(-1.8rem);
}
.slide-fade-enter-active { .slide-fade-enter-active {
transition: all 0.3s ease; transition: all 0.3s ease;
} }