CSS Layout & Selection System
Canvus manages node hierarchies and layouts by combining an in-memory tree model with CSS display introspection and canvas drop target estimation.
Hierarchical Tree Model (NodeTree)
The workspace doesn’t query the DOM repeatedly to determine parent-child relationships. Instead, NodeTree keeps an in-memory representation of the document structure.
- Node Hierarchy: Nodes contain
parentIdandchildIdsreferences. Root-level elements haveparentId = null - Topological Depth: The tree calculates a
depthindex (0 for root, 1 for direct children, etc.) for each node. This determines visual rendering order and breadcrumb paths - Reparenting Safety: When moving nodes, the tree runs cycle-detection algorithms. It walks ancestor branches of the target parent to ensure a node is never reparented to one of its own descendants
Mutation APIs
Always use the Workspace APIs to mutate structures:
ws.addNode(node, parentId, index) // Mount and register in NodeTree
ws.removeNode(nodeId) // Detach wrappers and clean tree
ws.reparentNode(nodeId, parentId) // Swap DOM parents and update tree
ws.reorderChild(nodeId, index) // Move sibling indexes and update childrenNever mutate parentId or childIds directly. Always use the Workspace mutation APIs to maintain safety invariants and prevent circular hierarchies.
Layout Introspection
The layout introspection engine (layout.ts) reads computed CSS variables from elements to determine visual overlay behavior.
Display Detection
When a container is measured, the engine calls getComputedStyle(element) to detect:
displaymode:flex,grid,block, orinline- Flex axes: Reads
flex-direction(row vs. column) andflex-wrapvalues - Grid configurations: Evaluates columns/rows and parses
gapdefinitions
Spacing Adjusters (Margins & Paddings)
When a single node is selected, Canvus renders hoverable margin/padding drag boxes on the canvas overlay:
- Reading Bounds: Reads computed margins (
margin-top,margin-left, etc.) and paddings - Visual Overlays: Paints drag bars representing padding (inside content boundaries) or margins (outside content boundaries) with values displayed in tooltips
- Style Surgery: Dragging an adjuster translates pointer coordinates into inline style changes. The browser reflows elements, the
ResizeObserverdetects changed rectangles, and the canvas overlay updates
Drop Zone & Drag-and-Drop Insertion
When a node is dragged, Canvus calculates potential placement zones in real-time.
Drop Target Estimation
- Container Hit Testing: Identifies which container node bounds cover the current pointer position
- Layout-Aware Slot Calculations:
- Flex Containers: Projects the pointer onto the active flex axis (row or column). Slices boundaries between existing children to identify index slots
- Grid Containers: Projects coordinates onto grid tracks (columns/rows) to resolve slot cells
- Block Flow: Measures vertical centerlines of siblings to find insertion slots
- Insertion Indicators: Draws horizontal or vertical coordinate lines on the canvas overlay
Figma-Style Selection Semantics
Canvus uses drill-down selection rules for navigating deeply nested hierarchies:
| Gesture | Behavior |
|---|---|
| Single Click | Selects the topmost element in the active scope. Clicking outside clears selection |
| Double Click | Drills down into the clicked node’s subtree scope |
| Cmd/Ctrl + Click | Deep selection — bypasses drill-down and directly selects the leaf node |
| Shift + Click | Multi-selection — adds or removes nodes from the selection set |