Configuration & Callbacks
WorkspaceConfig
Options passed to the Workspace constructor to customize interaction tolerances and visual appearance.
const ws = new Workspace(container, callbacks, {
overlayStyle: { ... },
snapThreshold: 5,
minResizeSize: 40,
enableSnapGuides: true,
viewport: { width: 960, height: 600 },
})| Property | Type | Default | Description |
|---|---|---|---|
overlayStyle | Partial<OverlayStyle> | See below | Overrides default canvas overlay colors, border widths, and fonts |
snapThreshold | number | 5 | Alignment guidelines snapping distance in canvas-space pixels |
minResizeSize | number | 40 | Minimum width or height allowed when resizing a node wrapper |
enableSnapGuides | boolean | true | Enables drawing snapping alignment lines during drag gestures |
viewport | ViewportConfig | undefined | Viewport scaling options for resolving CSS relative units (vh, vw) |
ViewportConfig
Options controlling the translation and scaling of CSS viewport units (vh, vw) relative to a simulated preview frame (canvas card) size.
interface ViewportConfig {
width: number;
height: number;
scaleViewportUnits?: boolean; // Defaults to true if viewport is defined
}When scaleViewportUnits is enabled, Canvus will:
- Define
--canvus-vhand--canvus-vwCSS variables on the root shadow DOM host, representing 1% of the cardβs width and height. - Automatically rewrite inline styles and injected stylesheet contents, translating
vhandvwintocalc(value * var(--canvus-vh/vw, 1vh/vw))so they scale relative to the frame rather than the window. - Automatically revert translated properties during
extractHTMLto keep the returned HTML clean and pristine. - Dynamically update custom variable properties when the root frame node is resized via workspace tools or public methods.
OverlayStyle
The full set of visual tokens controlling every aspect of the canvas overlay. All properties are optional when passed via Partial<OverlayStyle>.
interface OverlayStyle {
// ββ Selection βββββββββββββββββββββββββββ
selectionStroke: string // Selection border color (default: '#6366f1')
selectionWidth: number // Selection stroke width in px (default: 2)
selectionGlow: string // Glow shadow color (default: 'rgba(99,102,241,0.4)')
selectionGlowRadius: number // Glow blur radius (default: 12)
// ββ Hover βββββββββββββββββββββββββββββββ
hoverStroke: string // Hover outline color (default: 'rgba(99,102,241,0.6)')
hoverWidth: number // Hover stroke width (default: 1.5)
hoverDash: number[] // Hover dash pattern (default: [5, 5])
// ββ Resize Handles ββββββββββββββββββββββ
handleSize: number // Handle square size in px (default: 8)
handleFill: string // Handle fill color (default: '#ffffff')
handleStroke: string // Handle border color (default: '#6366f1')
handleStrokeWidth: number // Handle border width (default: 1.5)
handleRadius: number // Handle corner radius, 0 = square (default: 2)
handleHitRadius: number // Hit-test radius around handle center (default: 8)
handleActiveFill: string // Fill when actively dragging (default: '#6366f1')
// ββ Alignment Guides ββββββββββββββββββββ
guideStroke: string // Snap guide color (default: '#f43f5e')
guideWidth: number // Snap guide width (default: 1)
guideDash: number[] // Snap guide dash pattern (default: [4, 4])
// ββ Origin Crosshair ββββββββββββββββββββ
originStroke: string // Origin line color (default: 'rgba(99,102,241,0.12)')
originDash: number[] // Origin dash pattern (default: [6, 6])
// ββ Multi-Select ββββββββββββββββββββββββ
multiSelectStroke: string // Aggregate bounding box color (default: 'rgba(99,102,241,0.5)')
multiSelectDash: number[] // Aggregate box dash pattern (default: [6, 4])
// ββ Layout Badges βββββββββββββββββββββββ
layoutBadgeBg: string // Badge background (default: 'rgba(99,102,241,0.85)')
layoutBadgeText: string // Badge text color (default: '#ffffff')
layoutBadgeFont: string // Badge font (default: "600 9px 'Inter', system-ui")
// ββ Grid Tracks βββββββββββββββββββββββββ
gridTrackStroke: string // Grid track overlay color (default: 'rgba(99,102,241,0.2)')
gridTrackDash: number[] // Grid track dash pattern (default: [3, 3])
// ββ Scoped Selection ββββββββββββββββββββ
parentHighlightStroke: string // Parent outline when child is selected (default: 'rgba(99,102,241,0.35)')
childOutlineStroke: string // Available children outlines (default: 'rgba(99,102,241,0.18)')
// ββ Drag & Drop βββββββββββββββββββββββββ
dropZoneStroke: string // Drop container border (default: '#3b82f6')
dropZoneWidth: number // Drop zone stroke width (default: 2)
insertionLineStroke: string // Insertion line color (default: '#3b82f6')
insertionLineWidth: number // Insertion line width (default: 3)
}WorkspaceCallbacks
Hook callbacks triggered on workspace events. All callbacks are optional.
const ws = new Workspace(container, {
onHTMLCommit(id, html) { /* ... */ },
onNodeRectChange(id, rect) { /* ... */ },
onViewportChange(vp) { /* ... */ },
onSelectionChange(selectedIds) { /* ... */ },
onBreadcrumbChange(path) { /* ... */ },
onInteractionChange(mode) { /* ... */ },
onOperationsGenerated(ops) { /* ... */ },
onTextEditRequest(nodeId, element, commit) { /* ... */ },
})Callback Reference
onHTMLCommit
onHTMLCommit?: (id: string, html: string) => voidFlat String Bridge. Emits clean HTML string fragments (with wrappers stripped) after visual adjustments complete.
onNodeRectChange
onNodeRectChange?: (id: string, rect: Rect) => voidFired when a nodeβs bounding rect changes due to reflow or drag.
onViewportChange
onViewportChange?: (vp: Readonly<ViewportMatrix>) => voidFired when the workspace zoom level or pan offset shifts.
onSelectionChange
onSelectionChange?: (selectedIds: ReadonlySet<string>) => voidFired when the active selection is updated.
onBreadcrumbChange
onBreadcrumbChange?: (path: string[]) => voidFired when selection depth breadcrumbs are updated (drill-down navigation).
onInteractionChange
onInteractionChange?: (mode: string | null) => voidFired when the active drag state switches (e.g., "pan", "drag-node", "resize-node", null).
onOperationsGenerated
onOperationsGenerated?: (operations: Operation[]) => voidFired when a visual modification generates undoable history steps. See the Operations Guide for integration patterns.
onTextEditRequest
onTextEditRequest?: (
nodeId: string,
element: HTMLElement,
commit: (newHTML: string) => void
) => voidDouble-click escape hatch callback to mount custom rich text editor overlays. See the Custom Editor Guide for implementation examples.
onForcePseudoState
onForcePseudoState?: (
nodeId: string,
state: "hover" | "active" | "focus",
enabled: boolean
) => voidFired when a nodeβs pseudo-class state is modified via forceNodeState(). Use this to delegate pseudo-class forcing to the host β for example, via Chrome DevTools Protocol (CSS.forcePseudoState) in an Electron environment.
const ws = new Workspace(container, {
onForcePseudoState(nodeId, state, enabled) {
// e.g., Forward to CDP in Electron
cdp.send('CSS.forcePseudoState', {
nodeId: getDOMNodeId(nodeId),
forcedPseudoClasses: enabled ? [`:${state}`] : [],
})
},
})