Drag & Drop-віджети та пресети
1) Концепція та сценарії
Drag & Drop-віджети - інтерактивні блоки (картки графіків, таблиці, фільтри, кнопки-дії), які користувач вільно розміщує на полотні з прив'язкою до сітки. Пресети - збережені компонування і стилі (layout + тема + параметри), які можна швидко застосовувати, ділитися і версіонувати.
Типові сценарії:- Збірка дашборду з готових блоків (картки KPI, графіки, фільтри).
- Швидка зміна компонування через пресети «Компактний», «Аналітика», «Презентація».
- Спільне редагування: продакт розміщує віджети, аналітик налаштовує джерела.
- Публікація «тільки читання» для стейкхолдерів.
2) Архітектурні принципи
1. Grid-first: позиціонування в логічних колонках/рядках (12/24), пікселі - похідні.
2. Snapping & Guides: магнітні напрямні, прилипання до сітки і сусідів, вирівнювання.
3. Constraint-aware: обмежувачі розмірів/пропорцій, min/max, lock-aspect.
4. Safe-by-default: безперервне автозбереження, транзакційна публікація, undo/redo.
5. A11y-first: DnD з клавіатури і озвучування змін.
6. Realtime-ready: CRDT/OT для багатокористувацьких сесій.
7. Themable: дизайн-токени, пресети тем, режими світлий/темний/контрастний.
8. Portable: експорт/імпорт JSON/YAML; Версіонування схем.
3) Модель даних (спрощено)
json
{
"id": "layout_01",
"name": "Analytics - Compact,"
"version": "2. 1. 0",
"grid": { "cols": 12, "rowHeight": 8, "gutter": 8, "margin": 16 },
"theme": { "preset": "light-pro", "tokens": { "radius": 12, "elevation": "soft" } },
"widgets": [
{
"id": "w_kpi_1",
"type": "kpi",
"title": "GGR",
"pos": { "x": 0, "y": 0, "w": 3, "h": 4, "z": 1 },
"constraints": { "minW": 2, "minH": 3, "lockAspect": false },
"props": { "format": "currency", "source": "ggr_daily" }
},
{
"id": "w_chart_1",
"type": "lineChart",
"title": "Deposits Trend",
"pos": { "x": 3, "y": 0, "w": 6, "h": 8, "z": 1 },
"props": { "source": "deposits", "legend": true }
},
{
"id": "w_table_1",
"type": "table",
"title": "Top Segments",
"pos": { "x": 9, "y": 0, "w": 3, "h": 12, "z": 2 },
"props": { "source": "segments_top", "pageSize": 12 }
}
],
"meta": { "createdBy": "dima", "updatedAt": "2025-11-03T17:55:00Z" }
}
4) Грід, прив'язки і напрямні
Сітка: 12 колонок для десктопа, 6 - для планшета, 4 - для телефонів;'rowHeight'однаковий для стабільного вертикального кроку.
Snapping: прив'язка по краях/центрах; «магніти» на 4/8 px; розумні гайди при наближенні до сусідів.
Auto-flow: автоматичне перенесення нижче при колізії; алгоритм «падаючих блоків».
Респонсивність: breakpoints → альтернативні'pos'під кожен брейкпоінт.
5) DnD-події та стани
Події: `dragStart`, `drag`, `dragOver`, `drop`, `resizeStart`, `resize`, `resizeEnd`, `select`, `group`, `ungroup`, `reorder`, `undo`, `redo`.
Стани:- Ghost/Preview: напівпрозорий контур під час перетягування.
- Placeholders: допустимі зони (підсвічування зеленим), заборонені (червоним).
- Collision map: швидкий розрахунок зайнятих комірок (bitset/interval tree).
6) Ресайз, вирівнювання, z-index
Ручки ресайзу по кутах + утримання'Shift'для збереження пропорцій.
Вирівнювання групи: «по лівому/правому краю», «по центру», «розподілити рівномірно».
Рівні накладання: 'z'з обмеженням по діапазону, кнопки «спереду/ззаду».
7) Групи, контейнери та вкладеність
Групи: множинне виділення, спільне перетягування, групове вирівнювання.
Контейнер-віджети: таби, акордеони, каруселі - вміють приймати дочірні віджети.
Обмежувачі контейнера: зовнішня сітка ≠ внутрішня (інші колонки).
8) Пресети (шаблони) і версії
Типи пресетів: layout, тема (theme), «набір віджетів», «компонування + дані».
Версіонування: «semver» схеми та міграції (map полів, дефолти).
Preview & Apply: попередній перегляд до застосування.
Scoped presets: особисті, командні, глобальні; права на читання/редагування.
Експорт/імпорт: JSON/YAML, підпис контрольною сумою, перевірка сумісності версії.
9) Доступність (A11y) і клавіатура
Повний keyboard DnD:- «Enter/Space» - почати перенесення; стрілки - переміщення на крок сітки;'Shift'+ стрілки - прискорений крок;'Esc'- скасування.
- 'Ctrl/Cmd + G'- групувати;'Ctrl/Cmd + Shift + G'- розгрупувати.
- 'Alt'- тимчасово відключити прив'язку до сітки.
- Озвучка SR: "Переміщено на (x, y). Прилипання: включено. Конфлікт: так/ні".
- Фокус-кільця, великі ручки ресайзу, зони дропу з описом.
10) Тач і мобільні патерни
Long-press (300-500 мс) для старту DnD.
Збільшені таргети (мінімум 40-48 px).
Адаптивні панелі інструментів (нижня док-панель).
«Режим редагування»: блокування прокрутки полотна, вертикальний авто-скролл при перенесенні до краю.
11) Дії з віджетів (Actionable Widgets)
Вбудовані CTA (кнопка), контекстне меню, drag-clone (дублювання з утриманням'Alt').
«Швидкі пресети» для віджету (щільність, легенда, колірна схема).
Стани: loading/empty/error, безпечні заглушки («дані відстають»).
12) Спільна робота та публікації
Realtime: CRDT (наприклад, Yjs) або OT (Quill-підхід) - курсори учасників, блокування груп.
Права: `Owner`, `Editor`, `Viewer`; публікація знімка (immutable snapshot).
Потоки: чернетка → рев'ю → публікація; порівняння змін (diff layout'ів).
13) Undo/Redo і автозбереження
Командна шина: кожна операція - команда з'do/undo'.
Журнал на клієнті (in-memory + періодичний persist), ліміт по довжині.
Auto-save: кожні N секунд/по'idle', з індикатором «Збережено».
14) Темізація та дизайн-токени
json
{
"themeId": "light-pro",
"tokens": {
"fontScale": { "h1": 24, "h2": 18, "body": 14 },
"radius": 12,
"elevation": "soft",
"palette": { "primary": "#3366FF", "critical": "#E53935" }
}
}
Перемикання тем без перерахунку layout (тільки візуальні токени).
Контраст AA/AAA, режим High-Contrast, темна тема з коректним сірим.
15) Продуктивність
Відмальовка по шарах (canvas/webgl для складних графіків, DOM для хрому).
Віртуалізація списків/таблиць, throttle'drag'( 16 ms), requestAnimationFrame.
Диф-рендер: перемальовувати лише змінені віджети.
Кеш підрахунку колізій і гайдлайнів.
16) Безпека та захист контенту
Санбокс для HTML-віджетів (iframe, CSP,'sandbox'прапори).
Обмеження дропів: whitelist типів (файли, посилання, JSON пресетів); перевірка розміру та вмісту.
Права на пресети (RBAC/ABAC), аудит експорту/імпорту.
17) API віджетів (контракт)
ts interface Widget {
id: string;
type: string;
pos: { x:number; y:number; w:number; h:number; z:number };
constraints?: { minW?:number; minH?:number; maxW?:number; maxH?:number; lockAspect?:boolean };
props: Record<string, unknown>;
validate? (props): { ok: boolean; errors?: string[] };
onDrop? (dataTransfer): DropResult ;//support for external drop onAction? (actionId: string, payload?: any): void;
}
Події життєвого циклу: `mount`, `resize`, `visibilityChange`.
Валідація пропсів до публікації.
18) Імпорт/експорт та міграції
Експортує: `grid`, `widgets`, `theme`, `meta`.
Імпорт: перевірка версій схеми, автоматичні міграції (map полів/дефолти), звіт.
Lock-file пресета з хешем, щоб гарантувати цілісність.
19) Гарячі клавіші (рекомендовані)
Навігація: «←↑→↓» - переміщення; «Shift» + стрілки - швидкий крок.
Ресайз: 'Alt'+ стрілки.
Операції: 'Ctrl/Cmd + D'- дублікат;'Ctrl/Cmd + G'- група;'Ctrl/Cmd + Shift + G'- розгрупа.
Рівні: '['/']'- назад/вперед по z-index.
Undo/Redo: `Ctrl/Cmd+Z` / `Ctrl/Cmd+Shift+Z` (или `Y`).
Пресети: 'Ctrl/Cmd + 1.. 9'- швидко застосувати збережені.
20) UX-патерни
Швидкі гайди при першому запуску (мікро-онбординг на 3-5 кроків).
Режим сітки: перемикач «показати/приховати сітку».
Інлайн-підказки на колізіях ("недоступно: хв. ширина віджету = 3").
Історія макетів: повернення до попередньої версії.
21) Тест-план
Юніт: розрахунок колізій, снапінг, валідатор constraints.
Інтеграція: DnD мишею/тачем/клавіатурою; угруповання; Контейнери.
E2E: збірка дашборду «з нуля», застосування пресету, публікація, експорт/імпорт.
Хаос: затримки рендера, втрата з'єднання (realtime), конфлікт прав.
A11y: клавіатурні сценарії, SR-озвучка, контраст.
22) Чек-лист впровадження
- Сітка/брейкпоінти і снапінг налаштовані
- Ресайз/групи/вирівнювання працюють і протестовані
- Клавіатурний DnD і екранні підказки включені
- Автосейв, undo/redo, історія макетів
- Пресети: версії, права, експорт/імпорт
- Теми та дизайн-токени, режим High-Contrast
- Realtime-колаборація і вирішення конфліктів
- Обмеження дропів, валідація файлів, sandbox HTML
- Метрики: adoption, час до першого розміщення, помилки колізій
23) Міні-FAQ
Чому тільки сітка, а не вільні координати?
Сітка спрощує вирівнювання, адаптив, переносимість пресетів і продуктивність.
Як зберігати різні layout'и під брейкпоінти?
У кожного віджета -'pos'на брейкпоінт (desktop/tablet/mobile) з автоматичним fall-back.
Що вибрати для колаборації - OT або CRDT?
CRDT простіше для offline/конфліктів; OT - ок для лінійних текстових операцій. Для layout частіше беруть CRDT.
Підсумок
Хороші Drag & Drop-віджети - це не тільки «перетягнути картку». Це: сувора сітка та снапінг, зручні групи та вирівнювання, доступність з клавіатури, стабільні пресети з версіями та експортом, безпечні публікації та спільна робота. Побудуйте це навколо надійної моделі даних, продуманого UX і тест-плану - і конструктор стане швидким, зрозумілим і стійким до зростання контенту і команд.