1
0

Мобильная версия

1. Адаптация и разработка мобильного варианта.
This commit is contained in:
2026-01-15 09:33:16 +07:00
parent 901604afd4
commit 5018a2d123
23 changed files with 2787 additions and 171 deletions

View File

@@ -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>