Drag & Drop widgets and presets
1) Concept and scenarios
Drag & Drop widgets are interactive blocks (graph cards, tables, filters, action buttons) that the user freely places on the canvas with reference to the grid. Presets - saved layouts and styles (layout + theme + parameters) that can be quickly applied, shared and versioned.
Typical scenarios:- Assembly of dashboard from ready blocks (KPI cards, graphs, filters).
- Quick change of layout through the presets "Compact," "Analytics," "Presentation."
- Co-editing: the product places widgets, the analyst sets up sources.
- Read-only publication for stakeholders.
2) Architectural principles
1. Grid-first: positioning in logical columns/rows (12/24), pixels - derivatives.
2. Snapping & Guides: magnetic guides, sticking to mesh and neighbors, aligning.
3. Constraint-aware: size/aspect limiters, min/max, lock-aspect.
4. Safe-by-default: continuous autosave, transactional publishing, undo/redo.
5. A11y-first: DnD from the keyboard and voicing changes.
6. Realtime-ready: CRDT/OT for multiplayer sessions.
7. Themable: design tokens, theme presets, light/dark/contrast modes.
8. Portable: export/import JSON/YAML; circuit versioning.
3) Data model (simplified)
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) Grid, snaps and guides
Grid: 12 speakers for desktop, 6 for tablet, 4 for phones; 'rowHeight' is the same for stable vertical pitch.
Snapping: snap to edges/centers; "magnets" at 4/8 px; smart guides when approaching neighbors.
Auto-flow: automatic transfer below in case of collision; "falling blocks" algorithm.
Responsiveness: breakpoints → alternative 'pos' for each breakpoint.
5) DnD events and states
События: `dragStart`, `drag`, `dragOver`, `drop`, `resizeStart`, `resize`, `resizeEnd`, `select`, `group`, `ungroup`, `reorder`, `undo`, `redo`.
States:- Ghost/Preview-A translucent path while dragging.
- Placeholders: allowed zones (green), prohibited (red).
- Collision map - quick calculation of occupied cells (bitset/interval tree).
6) Raise, align, z-index
Resise grips at corners + hold'Shift 'to maintain proportions.
Alignment of the group: "left/right," "center," "distribute evenly."
Overlay levels: 'z' with range restriction, front/back buttons.
7) Groups, containers and nesting
Groups: multiple selection, combined drag and drop, group alignment.
Widget container: tabs, accordions, carousels - they know how to accept child widgets.
Container stops: external grid ≠ internal (other columns).
8) Presets (templates) and versions
Types of presets: layout, theme, widget set, layout + data.
Versioning: 'semver' schemes and migrations (field map, defaults).
Preview & Apply-Preview before applying.
Scoped presets: personal, team, global; read/edit rights.
Export/import: JSON/YAML, checksum signature, version compatibility check.
9) Accessibility (A11y) and keyboard
Full keyboard DnD:- 'Enter/Space '- start the transfer; arrows - move to grid spacing; 'Shift' + arrows - accelerated spacing; 'Esc' - cancel.
- 'Ctrl/Cmd + G '- group; 'Ctrl/Cmd + Shift + G' - ungroup.
- 'Alt '- temporarily turn off snapping to the grid.
- Voice acting SR: "Moved to (x, y). Sticking: on. Conflict: Yes/No."
- Focus rings, large recise handles, drop zones with a description.
10) Touch and mobile patterns
Long-press (300-500 ms) for DnD start.
Increased targets (minimum 40-48 px).
Adaptive toolbars (bottom dock).
Edit mode: canvas scrolling lock, vertical auto-scrolling when moving to the edge.
11) Actions from widgets (Actionable Widgets)
Built-in CTA (button), context menu, drag-clone (Alt-held duplication).
"Quick presets" for the widget (density, legend, color scheme).
States: loading/empty/error, secure stubs ("data is lagging").
12) Collaboration and Publishing
Realtime: CRDT (for example, Yjs) or OT (Quill approach) - participant cursors, group locks.
Rights: 'Owner', 'Editor', 'Viewer'; Publish an immutable snapshot.
Streams: draft → review → publication; comparison of changes (diff layouts).
13) Undo/Redo and autosave
Command bus: each operation is a command with 'do/undo'.
Log on the client (in-memory + periodic persist), length limit.
Auto-save: every N seconds/by'idle ', with "Saved" indicator.
14) Temization and design tokens
json
{
"themeId": "light-pro",
"tokens": {
"fontScale": { "h1": 24, "h2": 18, "body": 14 },
"radius": 12,
"elevation": "soft",
"palette": { "primary": "#3366FF", "critical": "#E53935" }
}
}
Switching themes without recalculating layout (visual tokens only).
AA/AAA contrast, High-Contrast mode, dark theme with correct gray.
15) Performance
Rendering by layers (canvas/webgl for complex graphs, DOM for chrome).
List/table virtualization, throttle 'drag' (16 ms), requestAnimationFrame.
Diff render: redraw only modified widgets.
Cache counting collisions and guidelines.
16) Content security and protection
Sunbox for HTML widgets (iframe, CSP, 'sandbox' flags).
Drop limitation: whitelist types (files, links, JSON presets); checking size and content.
Rights to presets (RBAC/ABAC), export/import audit.
17) Widget API (contract)
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;
}
Life cycle events are 'mount', 'resize', 'visibilityChange'.
Props validation prior to publication.
18) Import/export and migrations
Exports: 'grid', 'widgets', 'theme', 'meta'.
Import: checking schema versions, automatic migrations (field map/defaults), report.
Lock-file preset with hash to ensure integrity.
19) Hotkeys (recommended)
Navigation: '←↑→↓' - move; 'Shift' + arrows - quick step.
Recise: 'Alt' + arrows.
Operations: 'Ctrl/Cmd + D' - duplicate; 'Ctrl/Cmd + G' - group; 'Ctrl/Cmd + Shift + G' - ungroup.
Levels: '['/']' - back/forward on z-index.
Undo/Redo: `Ctrl/Cmd+Z` / `Ctrl/Cmd+Shift+Z` (или `Y`).
Presets: 'Ctrl/Cmd + 1.. 9' - quickly apply saved ones.
20) UX patterns
Quick guides at first launch (micro-onboarding for 3-5 steps).
Grid mode: toggle "show/hide grid."
Inline hints on collisions ("unavailable: minimum widget width = 3").
Layout History: Returns to the previous version.
21) Test plan
Unit: collision calculation, snapping, constraint validator.
Integration: DnD mouse/tap/keyboard; groupings; containers.
E2E: assembling a dashboard from scratch, applying a preset, publishing, exporting/importing.
Chaos: render delays, loss of connection (realtime), conflict of rights.
A11y: keyboard scripts, SR-voice acting, contrast.
22) Implementation checklist
- Grid/breakpoints and snapping configured
- Recise/groups/alignment work and tested
- Keyboard DnD and ScreenTips enabled
- Autosave, undo/redo, layout history
- Presets: versions, rights, export/import
- Themes and design tokens, High-Contrast mode
- Realtime collaboration and conflict resolution
- Drop limitation, file validation, sandbox HTML
- Metrics: adoption, time to first placement, collision errors
23) Mini-FAQ
Why only a grid, not free coordinates?
The grid simplifies alignment, coronavirus, preset portability and performance.
How to store different layouts for breakpoints?
Each widget has a'pos' on breakpoint (desktop/tablet/mobile) with automatic fall-back.
What to choose for the collaboration - OT or CRDT?
CRDT is easier for offline/conflicts; OT - ok for linear text operations. For layout, CRDT is more often taken.
Total
Good Drag & Drop widgets are not only "drag and drop." These are: strict grid and snapping, convenient groups and alignment, keyboard accessibility, stable presets with versions and exports, secure publications and collaboration. Build this around a reliable data model, a well-thought-out UX and a test plan - and the constructor will become fast, understandable and resistant to the growth of content and commands.