Files
sfera-new/docs/presentation-layer/CSS_LAYOUT_SCROLL_RULES.md
Veronika Smirnova 121a4dece1 docs: создать правила для синхронизации данных, layout и статистических компонентов
- DATA_SYNCHRONIZATION_RULES.md - правила синхронизации между компонентами
- GRAPHQL_CACHE_RULES.md - настройки кеширования и fetchPolicy
- CSS_LAYOUT_SCROLL_RULES.md - решение проблем с overflow и scroll
- STATISTICAL_COMPONENTS_RULES.md - правила Master-Detail архитектуры

Документация основана на исправлениях в кабинете фулфилмента

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-27 12:29:00 +03:00

490 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 🎨 ПРАВИЛА CSS LAYOUT И СКРОЛЛА
> **Цель:** Предотвратить проблемы с overflow, scroll и позиционированием в Next.js 15 + React 19 приложении
## 📋 **ОСНОВНЫЕ ПРИНЦИПЫ LAYOUT**
### 1. **БАЗОВАЯ АРХИТЕКТУРА LAYOUT**
```typescript
// ✅ ПРАВИЛЬНАЯ структура для всех страниц приложения
<div className="h-screen flex overflow-hidden"> {/* Контейнер полной высоты */}
<Sidebar /> {/* Фиксированная боковая панель */}
<main className={`
flex-1 /* Занимает оставшееся место */
${getSidebarMargin()} /* Динамический отступ */
px-4 py-3 /* Внутренние отступы */
flex flex-col /* Вертикальная компоновка */
transition-all duration-300 /* Плавные анимации */
overflow-hidden /* Предотвращение двойного скролла */
`}>
<div className="flex-1 overflow-y-auto space-y-6"> {/* ЕДИНСТВЕННАЯ зона скролла */}
{/* Весь контент здесь */}
</div>
</main>
</div>
```
### 2. **КРИТИЧЕСКИЕ ПРАВИЛА OVERFLOW**
#### **✅ ПРАВИЛЬНО: Один уровень overflow**
```css
/* Родительский контейнер */
.container {
height: 100vh;
overflow: hidden; /* Запрещаем скролл на уровне экрана */
}
/* Дочерний скроллируемый контейнер */
.scrollable-content {
flex: 1;
overflow-y: auto; /* ЕДИНСТВЕННАЯ зона скролла */
}
```
#### **❌ НЕПРАВИЛЬНО: Множественные overflow зоны**
```css
/* Создаёт конфликты скролла */
.parent {
overflow-y: auto; /* Первый скролл */
}
.child {
overflow-y: auto; /* Второй скролл - ПРОБЛЕМА! */
}
```
---
## 🚨 **ТИПИЧНЫЕ ПРОБЛЕМЫ И РЕШЕНИЯ**
### **ПРОБЛЕМА 1: Контент смещается вправо**
**❌ Причина:**
```jsx
<div style={{ minHeight: '200vh' }}>
{' '}
{/* Принудительная высота */}
<div className="overflow-hidden">
{' '}
{/* Скрывает контент */}
{/* Контент не помещается и смещается */}
</div>
</div>
```
**✅ Решение:**
```jsx
<div className="space-y-6">
{' '}
{/* Простая вертикальная компоновка */}
{/* Контент автоматически размещается правильно */}
</div>
```
### **ПРОБЛЕМА 2: Скролл не работает**
**❌ Причина:**
```jsx
<div className="h-screen overflow-hidden">
{' '}
{/* Блокирует скролл */}
<div className="overflow-hidden">
{' '}
{/* Дублирует блокировку */}
<div className="min-h-[200vh]">
{' '}
{/* Создаёт контент больше экрана */}
{/* Контент не скроллится */}
</div>
</div>
</div>
```
**✅ Решение:**
```jsx
<div className="h-screen flex flex-col overflow-hidden">
<div className="flex-1 overflow-y-auto">
{' '}
{/* ЕДИНСТВЕННАЯ зона скролла */}
{/* Контент свободно скроллится */}
</div>
</div>
```
### **ПРОБЛЕМА 3: Двойной sidebar в layout**
**❌ Причина:**
```jsx
// В page.tsx
<div className="flex">
<Sidebar /> {/* Первый sidebar */}
<main>
<div className="flex">
<Sidebar /> {/* Второй sidebar - ДУБЛИРОВАНИЕ! */}
<content />
</div>
</main>
</div>
```
**✅ Решение:**
```jsx
// В page.tsx - УБРАТЬ дублирование
<div className="h-screen flex overflow-hidden">
<Sidebar /> {/* ЕДИНСТВЕННЫЙ sidebar */}
<main className={`flex-1 ${getSidebarMargin()} overflow-hidden`}>
<div className="flex-1 overflow-y-auto space-y-6">{/* Весь контент */}</div>
</main>
</div>
```
---
## 🏗️ **АРХИТЕКТУРНЫЕ ПАТТЕРНЫ**
### **ПАТТЕРН 1: Dashboard с статистикой**
```jsx
export function DashboardPage() {
return (
<div className="h-screen flex overflow-hidden">
<Sidebar />
<main className={`flex-1 ${getSidebarMargin()} px-4 py-3 flex flex-col overflow-hidden`}>
<div className="flex-1 overflow-y-auto space-y-6">
{/* Заголовок */}
<Header />
{/* Статистические карточки */}
<StatsCards />
{/* Основное содержимое */}
<MainContent />
</div>
</main>
</div>
)
}
```
### **ПАТТЕРН 2: Таблица с фильтрами**
```jsx
export function TablePage() {
return (
<div className="h-screen flex overflow-hidden">
<Sidebar />
<main className={`flex-1 ${getSidebarMargin()} px-4 py-3 flex flex-col overflow-hidden`}>
<div className="flex-1 overflow-y-auto space-y-6">
{/* Фильтры (фиксированные) */}
<FiltersPanel />
{/* Таблица (скроллируемая) */}
<div className="flex-1 overflow-y-auto">
<DataTable />
</div>
</div>
</main>
</div>
)
}
```
### **ПАТТЕРН 3: Модальные окна**
```jsx
// ✅ Модалки не должны влиять на основной скролл
<Dialog>
<div className="max-h-[80vh] overflow-y-auto">
{' '}
{/* Скролл только внутри модалки */}
<ModalContent />
</div>
</Dialog>
```
---
## 📱 **RESPONSIVE DESIGN ПРАВИЛА**
### **АДАПТИВНЫЕ КОНТЕЙНЕРЫ**
```jsx
<div
className="
grid
grid-cols-1 /* Мобильные: 1 колонка */
md:grid-cols-2 /* Планшеты: 2 колонки */
lg:grid-cols-4 /* Десктоп: 4 колонки */
xl:grid-cols-6 /* Большие экраны: 6 колонок */
gap-4
"
>
{/* Карточки адаптивно размещаются */}
</div>
```
### **АДАПТИВНЫЕ ОТСТУПЫ**
```jsx
<main className={`
flex-1
${getSidebarMargin()} /* Динамический отступ для sidebar */
px-4 py-3 /* Базовые отступы */
lg:px-6 lg:py-4 /* Увеличенные отступы на больших экранах */
overflow-hidden
`}>
```
---
## 🎯 **СПЕЦИФИЧЕСКИЕ ПРАВИЛА ДЛЯ SFERA**
### **ПРАВИЛА ДЛЯ ФУЛФИЛМЕНТ КОМПОНЕНТОВ**
#### **1. Главная страница склада**
```jsx
// src/app/fulfillment-warehouse/page.tsx
<div className="h-screen flex overflow-hidden">
<Sidebar />
<main className={`flex-1 ${getSidebarMargin()} px-4 py-3 flex flex-col overflow-hidden`}>
<div className="flex-1 overflow-y-auto space-y-6">
<WarehouseHeader />
<WarehouseStats /> {/* Статистика - НЕ скроллится */}
<WarehouseContent /> {/* Контент - скроллится */}
</div>
</main>
</div>
```
#### **2. Таблицы поставок**
```jsx
// src/components/fulfillment-warehouse/fulfillment-supplies-page.tsx
<div className="h-screen flex overflow-hidden">
<Sidebar />
<main className={`flex-1 ${getSidebarMargin()} px-4 py-3 flex flex-col overflow-hidden`}>
<div className="flex-1 overflow-y-auto space-y-6">
{' '}
{/* ← КЛЮЧЕВОЙ ЭЛЕМЕНТ */}
<SuppliesHeader /> {/* Фильтры */}
<SuppliesStats /> {/* Статистика */}
<SuppliesList /> {/* Основная таблица - скроллируется естественно */}
</div>
</main>
</div>
```
#### **3. Раскрывающиеся детали (Master-Detail)**
```jsx
// Детали поставок в раскрывающихся строках
<tr className="border-t border-white/10">
<td colSpan="100%" className="p-0">
<div className="max-h-96 overflow-y-auto bg-white/5">
{' '}
{/* Локальный скролл */}
<DeliveryDetails />
</div>
</td>
</tr>
```
---
## ⚡ **ПРОИЗВОДИТЕЛЬНОСТЬ И ОПТИМИЗАЦИЯ**
### **ВИРТУАЛИЗАЦИЯ ДЛЯ БОЛЬШИХ СПИСКОВ**
```jsx
// Для таблиц с >100 строк
import { FixedSizeList as List } from 'react-window'
;<div className="h-96 overflow-hidden">
{' '}
{/* Контейнер фиксированной высоты */}
<List
height={384} // Высота контейнера
itemCount={items.length} // Количество элементов
itemSize={64} // Высота каждого элемента
className="scrollbar-thin" // Кастомный скроллбар
>
{({ index, style }) => (
<div style={style}>
<TableRow item={items[index]} />
</div>
)}
</List>
</div>
```
### **LAZY LOADING ДЛЯ КОНТЕНТА**
```jsx
const LazyTableSection = lazy(() => import('./TableSection'))
// В компоненте
<div className="flex-1 overflow-y-auto space-y-6">
<StatsSection /> {/* Загружается сразу */}
<Suspense fallback={<div>Загрузка...</div>}>
<LazyTableSection /> {/* Загружается по требованию */}
</Suspense>
</div>
```
---
## 🚨 **АНТИ-ПАТТЕРНЫ И ЗАПРЕТЫ**
### **❌ НИКОГДА НЕ ДЕЛАЙТЕ:**
#### **1. Принудительные размеры**
```jsx
// ❌ Создаёт проблемы с layout
<div style={{ minHeight: '200vh' }}>
<div className="h-[2000px]">
```
#### **2. Множественные overflow зоны**
```jsx
// ❌ Конфликты скролла
<div className="overflow-y-auto">
<div className="overflow-y-auto">
<div className="overflow-y-auto">
```
#### **3. Смешивание fixed и sticky позиционирования**
```jsx
// ❌ Непредсказуемое поведение
<div className="fixed top-0">
<div className="sticky top-0">
```
#### **4. Игнорирование responsive дизайна**
```jsx
// ❌ Не адаптируется к мобильным устройствам
<div className="grid grid-cols-6 gap-4"> {/* Сломается на мобильных */}
```
---
## 🔧 **ИНСТРУМЕНТЫ ОТЛАДКИ**
### **CSS DEBUG КЛАССЫ**
```css
/* Добавьте для визуализации проблем */
.debug-borders * {
border: 1px solid red !important;
}
.debug-overflow {
overflow: visible !important;
background: rgba(255, 0, 0, 0.1) !important;
}
.debug-scroll {
scrollbar-color: red transparent !important;
scrollbar-width: thick !important;
}
```
### **REACT DevTools**
```jsx
// Добавьте data-атрибуты для отладки
<div
className="overflow-y-auto"
data-scroll-zone="main-content"
data-debug="scroll-container"
>
```
### **КОНСОЛЬНЫЕ ЛОГИ ДЛЯ РАЗМЕРОВ**
```jsx
useEffect(() => {
const element = ref.current
if (element) {
console.log('LAYOUT DEBUG:', {
scrollHeight: element.scrollHeight,
clientHeight: element.clientHeight,
offsetHeight: element.offsetHeight,
hasOverflow: element.scrollHeight > element.clientHeight,
})
}
}, [])
```
---
## 📊 **ЧЕКЛИСТ ПРОВЕРКИ LAYOUT**
### **Перед релизом:**
- [ ] Единственная зона скролла на странице
- [ ] Нет принудительных высот (`minHeight: '200vh'`)
- [ ] Правильная структура с `h-screen` и `overflow-hidden`
- [ ] Responsive дизайн для мобильных устройств
- [ ] Sidebar не дублируется в компонентах
- [ ] Модальные окна не влияют на основной скролл
### **При проблемах со скроллом:**
- [ ] Проверить количество `overflow-y-auto` в иерархии
- [ ] Убедиться в отсутствии `overflow-hidden` на скроллируемом контейнере
- [ ] Проверить наличие `flex-1` у родительского контейнера
- [ ] Убрать принудительные размеры (`min-height`, `height: 200vh`)
---
## 🎨 **КАСТОМНЫЕ СКРОЛЛБАРЫ**
### **TAILWIND CLASSES**
```jsx
<div className="
overflow-y-auto
scrollbar-thin /* Тонкий скроллбар */
scrollbar-track-transparent
scrollbar-thumb-white/20
hover:scrollbar-thumb-white/30
">
```
### **CUSTOM CSS**
```css
/* Кастомные скроллбары для SFERA */
.custom-scrollbar::-webkit-scrollbar {
width: 8px;
}
.custom-scrollbar::-webkit-scrollbar-track {
background: transparent;
}
.custom-scrollbar::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.2);
border-radius: 4px;
}
.custom-scrollbar::-webkit-scrollbar-thumb:hover {
background: rgba(255, 255, 255, 0.3);
}
```
**Следование этим правилам обеспечит корректную работу layout и скролла во всех компонентах!** 🚀