Мобильная версия
1. Адаптация и разработка мобильного варианта.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="board">
|
||||
<div class="columns">
|
||||
<div class="board" :class="{ mobile: isMobile }">
|
||||
<div class="columns" ref="columnsRef" @scroll="onColumnsScroll">
|
||||
<Column
|
||||
v-for="column in filteredColumns"
|
||||
:key="column.id"
|
||||
@@ -14,6 +14,21 @@
|
||||
@archive-task="archiveTask"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Мобильный индикатор снизу (над навигацией) -->
|
||||
<div v-if="isMobile" class="mobile-column-footer">
|
||||
<div class="current-column-title">{{ currentColumnTitle }}</div>
|
||||
<div class="column-indicators">
|
||||
<button
|
||||
v-for="(column, index) in filteredColumns"
|
||||
:key="column.id"
|
||||
class="indicator-dot"
|
||||
:class="{ active: currentColumnIndex === index }"
|
||||
:style="{ '--dot-color': column.color }"
|
||||
@click="scrollToColumn(index)"
|
||||
></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -21,6 +36,35 @@
|
||||
import { ref, computed, onMounted, onUpdated, watch } from 'vue'
|
||||
import Column from './Column.vue'
|
||||
import { cardsApi } from '../api'
|
||||
import { useMobile } from '../composables/useMobile'
|
||||
|
||||
const { isMobile } = useMobile()
|
||||
|
||||
// Мобильный свайп
|
||||
const columnsRef = ref(null)
|
||||
const currentColumnIndex = ref(0)
|
||||
|
||||
const onColumnsScroll = () => {
|
||||
if (!columnsRef.value || !isMobile.value) return
|
||||
const scrollLeft = columnsRef.value.scrollLeft
|
||||
const columnWidth = columnsRef.value.scrollWidth / filteredColumns.value.length
|
||||
currentColumnIndex.value = Math.round(scrollLeft / columnWidth)
|
||||
}
|
||||
|
||||
const scrollToColumn = (index) => {
|
||||
if (!columnsRef.value) return
|
||||
const columnWidth = columnsRef.value.scrollWidth / filteredColumns.value.length
|
||||
columnsRef.value.scrollTo({
|
||||
left: index * columnWidth,
|
||||
behavior: 'smooth'
|
||||
})
|
||||
}
|
||||
|
||||
// Название текущей колонки для мобильного индикатора
|
||||
const currentColumnTitle = computed(() => {
|
||||
const col = filteredColumns.value[currentColumnIndex.value]
|
||||
return col ? col.title : ''
|
||||
})
|
||||
|
||||
const props = defineProps({
|
||||
activeDepartment: Number,
|
||||
@@ -277,4 +321,76 @@ defineExpose({ saveTask, deleteTask, archiveTask })
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
/* ========== MOBILE: колонки со свайпом ========== */
|
||||
.board.mobile {
|
||||
min-width: auto;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.board.mobile .columns {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
gap: 0;
|
||||
padding: 0;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
scroll-snap-type: x mandatory;
|
||||
scroll-behavior: smooth;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
/* Отключаем вертикальный скролл на уровне этого элемента */
|
||||
overscroll-behavior: contain;
|
||||
touch-action: pan-x;
|
||||
}
|
||||
|
||||
.board.mobile .columns::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Мобильный футер с индикатором колонок */
|
||||
.mobile-column-footer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 12px 16px;
|
||||
background: var(--bg-body);
|
||||
flex-shrink: 0;
|
||||
min-height: 60px;
|
||||
}
|
||||
|
||||
.current-column-title {
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: var(--text-secondary);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.column-indicators {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.indicator-dot {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
border: none;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.indicator-dot.active {
|
||||
width: 28px;
|
||||
border-radius: 5px;
|
||||
background: var(--dot-color, var(--accent));
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user