TimelixTimelix
Блочная система

Режимы отображения

List, Flow и Grid — как работает каждый режим отображения блоков

Каждый контейнерный блок может отображать своих дочерних блоков в одном из трёх режимов. Режим выбирается пользователем и хранится в поле layoutData.mode родительского блока.

Система запоминает настройки для всех трёх режимов одновременно. При переключении между режимами позиции и настройки каждого сохраняются — ничего не теряется.

Ключевое правило: родительский контроль

Позиции дочерних блоков (где они находятся на полотне) хранятся в родительском блоке в поле layoutData, а не в самих дочерних блоках. Дочерние блоки ничего не знают о своём расположении.

parentBlock.layoutData = {
  mode: 'grid',
  list: { order: ['id1', 'id2', 'id3'] },
  flow: { nodes: [...], edges: [...] },
  grid: { layouts: { lg: [...], md: [...] } }
}

При изменении позиции — запрос идёт к родителю, а не к дочернему блоку.


List

Простой вертикальный список. Блоки расположены один под другим в заданном порядке.

Когда использовать: задачи, заметки, линейные документы, todo-листы.

Компонент: BlockList

// layoutData.list
{
  order: string[];  // порядок ID дочерних блоков
}

Перестановка блоков — drag & drop по вертикали, обновляет массив order.


Flow

Свободное холст-позиционирование на базе React Flow. Блоки можно свободно перемещать, соединять стрелками, зумировать.

Когда использовать: майндмэпы, связи между концепциями, диаграммы зависимостей, brainstorming.

Компонент: BlockFlowView

// layoutData.flow
{
  nodes: Array<{
    id: string;           // ID блока
    position: { x: number; y: number };
    data: Record<string, unknown>;
  }>;
  edges: Array<{
    id: string;
    source: string;
    target: string;
    label?: string;
  }>;
  viewport?: { x: number; y: number; zoom: number };
}

Компонент BlockFlowView инкапсулирует только логику React Flow. Вся остальная логика (загрузка данных, сохранение позиций, управление блоками) передаётся через пропсы снаружи.


Grid

Сетка с настраиваемыми размерами на базе react-grid-layout. Каждый блок занимает прямоугольную область, размер которой можно менять перетаскиванием.

Когда использовать: дашборды, рабочие столы, виджеты с разными размерами.

Компонент: BlockGrid
Хук: useGridEditMode

// layoutData.grid
{
  layouts: {
    lg: Array<{ i: string; x: number; y: number; w: number; h: number }>;
    md: Array<{ i: string; x: number; y: number; w: number; h: number }>;
    sm: Array<{ i: string; x: number; y: number; w: number; h: number }>;
  };
  cols?: { lg: number; md: number; sm: number };  // по умолчанию 12/6/4
}

Поле i в каждом элементе — это ID блока.

Режим редактирования Grid

По умолчанию Grid работает в режиме просмотра. Для изменения позиций нужно включить режим редактирования через useGridEditMode:

const { isEditMode, toggleEditMode } = useGridEditMode();

В режиме редактирования блоки можно перетаскивать и изменять размер. При выходе из режима изменения сохраняются.


Переключение режимов

const { setMode } = useViewSettings();
 
// Переключить на Flow
setMode('flow');
 
// Переключить на Grid
setMode('grid');
 
// Вернуться к List
setMode('list');

useViewSettings автоматически сохраняет выбранный режим и синхронизирует его между вкладками браузера.


Правила разработки компонентов режимов

  1. Изоляция библиотеки — компонент режима работает только с логикой своей библиотеки (ReactFlow, GridLayout). Всё остальное — через пропсы.
  2. Никакой бизнес-логики — никаких useEffect с данными, никакого прямого обращения к API.
  3. Простота — максимум 300–400 строк на компонент.
// ✅ Правильно: логика снаружи, компонент только рендерит
<BlockFlowView
  nodes={nodes}
  edges={edges}
  onNodeMove={handleNodeMove}
  onEdgeCreate={handleEdgeCreate}
/>
 
// ❌ Неправильно: компонент сам загружает данные
const BlockFlowView = () => {
  const { data } = useQuery(...); // бизнес-логика в компоненте
  ...
};

On this page