keanu-weblite/src/components/BottomSheet.vue
2025-10-19 14:05:29 +03:00

131 lines
2.4 KiB
Vue

<template>
<div
class="bottom-sheet"
ref="sheet"
:style="state == 'closed' ? { 'pointer-events': 'none' } : {}"
>
<v-fade-transition>
<div
class="bottom-sheet-bg"
v-show="state != 'closed'"
@click.stop="onBackgroundClick"
/>
</v-fade-transition>
<div
class="bottom-sheet-content"
:data-state="state"
ref="pan"
>
<v-container>
<v-row justify="end">
<v-col cols="1" class="text-right">
<v-btn
size="small"
elevation="0"
@click.stop="onBackgroundClick"
icon="close"
>
</v-btn>
</v-col>
</v-row>
</v-container>
<div ref="sheetContent" class="sheetContent">
<slot></slot>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
state: "closed"
};
},
methods: {
open() {
this.setState("small");
},
close() {
this.setState("closed");
},
setState(state) {
this.state = state;
if (state == "closed") {
this.scrollToTop();
}
},
onBackgroundClick() {
if (this.state == "open") {
this.setState("small");
} else {
this.setState("closed");
}
},
scrollToTop() {
const container = this.$refs.sheetContent;
if (container) {
container.scrollTo(0, 0);
}
},
},
};
</script>
<style lang="scss" scoped>
@use 'vuetify/settings' as *;
@use '@/assets/css/variables' as *;
@use "sass:map";
.sheetContent {
position:absolute;
top: 60px;
padding: 0 20px 20px 20px;
left:0;
right:0;
bottom:0;
overflow-y:auto;
border-top: 1px solid #E1E1E1;
}
.bottom-sheet {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
overflow-x: hidden;
overflow-y: hidden;
z-index: 20;
}
.bottom-sheet-bg {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(black, 0.4);
}
.bottom-sheet-content {
position: absolute;
top: 100px;
bottom: 0px;
left: 0;
right: 0;
border-radius: 10px 10px 0px 0px;
background-color: white;
overflow: hidden;
&[data-state="small"], &[data-state="open"], &[data-state="closed"] {
transition: top 0.3s ease-out;
}
@media #{map.get($display-breakpoints, 'lg-and-up')} {
margin: 0 auto;
width: $dialog-desktop-width;
}
}
</style>