Мобильная версия
1. Адаптация и разработка мобильного варианта.
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
>
|
||||
<div
|
||||
class="panel"
|
||||
:class="{ mobile: isMobile }"
|
||||
:style="{ width: panelWidth + 'px' }"
|
||||
ref="panelRef"
|
||||
@mousedown="overlayMouseDownTarget = false"
|
||||
@@ -41,6 +42,9 @@
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, onUnmounted, onUpdated, watch } from 'vue'
|
||||
import { useMobile } from '../../composables/useMobile'
|
||||
|
||||
const { isMobile } = useMobile()
|
||||
|
||||
const props = defineProps({
|
||||
show: {
|
||||
@@ -142,10 +146,22 @@ const refreshIcons = () => {
|
||||
}
|
||||
}
|
||||
|
||||
// Блокировка скролла body при открытии панели
|
||||
const lockBodyScroll = () => {
|
||||
document.body.classList.add('panel-open')
|
||||
}
|
||||
|
||||
const unlockBodyScroll = () => {
|
||||
document.body.classList.remove('panel-open')
|
||||
}
|
||||
|
||||
// Восстановление ширины при открытии (из localStorage или дефолтная)
|
||||
watch(() => props.show, (newVal) => {
|
||||
if (newVal) {
|
||||
panelWidth.value = getSavedWidth()
|
||||
lockBodyScroll()
|
||||
} else {
|
||||
unlockBodyScroll()
|
||||
}
|
||||
})
|
||||
|
||||
@@ -155,6 +171,7 @@ onUpdated(refreshIcons)
|
||||
onUnmounted(() => {
|
||||
document.removeEventListener('mousemove', onResize)
|
||||
document.removeEventListener('mouseup', stopResize)
|
||||
unlockBodyScroll()
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -164,6 +181,9 @@ onUnmounted(() => {
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
z-index: 1000;
|
||||
/* Блокируем горизонтальные свайпы на мобильных */
|
||||
touch-action: pan-y pinch-zoom;
|
||||
overscroll-behavior: contain;
|
||||
}
|
||||
|
||||
.panel {
|
||||
@@ -172,6 +192,7 @@ onUnmounted(() => {
|
||||
right: 0;
|
||||
max-width: 100%;
|
||||
height: 100vh;
|
||||
height: 100dvh; /* Динамическая высота для iOS */
|
||||
background: #18181b;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -205,9 +226,10 @@ onUnmounted(() => {
|
||||
|
||||
.header-content {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.header-content :deep(h2) {
|
||||
@@ -216,11 +238,21 @@ onUnmounted(() => {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.header-content :deep(.header-title-block) {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.header-content :deep(.header-date) {
|
||||
font-size: 13px;
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.header-content :deep(.header-tabs) {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.btn-close {
|
||||
background: none;
|
||||
border: none;
|
||||
@@ -299,4 +331,38 @@ onUnmounted(() => {
|
||||
.panel-leave-to .panel {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
|
||||
/* ========== MOBILE: Fullscreen ========== */
|
||||
.panel.mobile {
|
||||
width: 100% !important;
|
||||
max-width: 100%;
|
||||
border-radius: 0;
|
||||
/* Блокируем горизонтальные свайпы, чтобы не срабатывала навигация браузера */
|
||||
touch-action: pan-y pinch-zoom;
|
||||
overscroll-behavior: contain;
|
||||
}
|
||||
|
||||
.panel.mobile .resize-handle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.panel.mobile .panel-header {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.panel.mobile .panel-body {
|
||||
padding: 16px;
|
||||
padding-bottom: calc(16px + var(--safe-area-bottom, 0px));
|
||||
min-height: 0; /* Важно для flex overflow */
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.panel.mobile .panel-footer {
|
||||
padding: 16px;
|
||||
padding-bottom: calc(16px + var(--safe-area-bottom, 0px));
|
||||
}
|
||||
|
||||
.panel.mobile .header-content :deep(h2) {
|
||||
font-size: 18px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user