Layout Guides

Overview

@designful/layout-guides-plugin provides per-frame layout guides.

The package name still says layout-guides, but the feature now supports multiple layout guides per frame, matching Figma-style square, column, and row guides more closely.

For the plugin-focused guide and live demo routes, see:

Dynamic Enable

const { ensureLayoutGuidesPlugin } = await import('@designful/layout-guides-plugin')

const layoutGuides = ensureLayoutGuidesPlugin(editor)

@designful/editor-core does not statically import this package, so you can enable it only when a page needs layout guides.

Add Guides To A Frame

editor.layoutGuides?.addFrameGuide(frameId, {
  mode: 'square',
  size: 16,
})

editor.layoutGuides?.addFrameGuide(frameId, {
  mode: 'columns',
  sizing: 'stretch',
  count: 6,
  gutter: 16,
  margin: 24,
})

You can also replace the whole frame guide list in one call:

editor.layoutGuides?.replaceFrameGuides(frameId, [
  { mode: 'square', size: 16 },
  { mode: 'rows', sizing: 'fixed', count: 'auto', gutter: 12, rowHeight: 48, alignment: 'center', offset: 0 },
])

Context Menu

  1. Right-click a single frame.
  2. Open Layout Guides.
  3. Use Add Guide or the per-guide submenu under Guides.

API calls and context-menu actions both use the same validation and command path.

Supported Guide Types

Square

editor.layoutGuides?.addFrameGuide(frameId, {
  mode: 'square',
  size: 16,
  color: '#2563eb',
  opacity: 0.24,
})

Columns / Stretch

editor.layoutGuides?.addFrameGuide(frameId, {
  mode: 'columns',
  sizing: 'stretch',
  count: 4,
  gutter: 20,
  margin: 24,
})

Columns / Fixed

editor.layoutGuides?.addFrameGuide(frameId, {
  mode: 'columns',
  sizing: 'fixed',
  count: 'auto',
  gutter: 16,
  columnWidth: 64,
  alignment: 'center',
  offset: 0,
})

Rows / Stretch

editor.layoutGuides?.addFrameGuide(frameId, {
  mode: 'rows',
  sizing: 'stretch',
  count: 6,
  gutter: 12,
  margin: 16,
})

Rows / Fixed

editor.layoutGuides?.addFrameGuide(frameId, {
  mode: 'rows',
  sizing: 'fixed',
  count: 'auto',
  gutter: 12,
  rowHeight: 48,
  alignment: 'bottom',
  offset: 12,
})

Presets, Clipboard, And Global Visibility

editor.layoutGuides?.savePreset(frameId, 'Dashboard Guides')
editor.layoutGuides?.applyPreset(otherFrameId, presetId)
editor.layoutGuides?.copyFrameGuides(frameId)
editor.layoutGuides?.pasteFrameGuides(otherFrameId, { replace: true })
editor.layoutGuides?.toggleGlobalVisibility(false)
  • Presets are stored on current page metadata.
  • Global visibility hides overlays without deleting frame guide data.
  • Copy/paste clones guide ids so pasted guides remain independent.

Update Or Remove

editor.layoutGuides?.updateFrameGuide(frameId, guideId, { opacity: 0.32 })
editor.layoutGuides?.toggleFrameGuide(frameId, guideId, false)
editor.layoutGuides?.removeFrameGuide(frameId, guideId)
editor.layoutGuides?.removeFrameGuides(frameId)
  • toggleFrameGuide(..., false) keeps the guide data but hides that guide.
  • removeFrameGuides(frameId) removes all stored guides from the frame.

Validation Rules

The plugin rejects commands when:

  • the target object is missing
  • the target object is not a frame
  • the frame is locked
  • square guide size is smaller than 1
  • the requested layout does not fit inside the frame
  • the frame exceeds maxGuidesPerFrame

Why Aren't My Layout Guides Showing?

A layout-guide overlay can stay hidden for a few different reasons:

  • all guides on the frame are toggled off
  • layout guides are toggled off globally
  • the selected layer is not a frame
  • the frame has been rotated away from

These rules match the runtime helper exported by the package: resolveLayoutGuideVisibilityReason(...). Rotated frames keep their guide data, but the overlay stays hidden until rotation returns to .

History And Persistence

Frame-level guide data is stored at:

frame.metadata.plugins.layoutGuides

Page-level plugin state is stored at:

page.metadata.layoutGuidesPlugin

Because the plugin mirrors page-level state into history-index snapshots:

  • save/load keeps the latest page-scoped presets
  • undo and redo restore global visibility and preset lists
  • history jumps rebuild overlays from the correct frame metadata
  • rotated frames keep their guide data but do not render overlays
  • deleted frames remove their overlays without leaving orphans