From aa6a8fa5a9efc3c382b0f3758e4c0d8842cd1159 Mon Sep 17 00:00:00 2001 From: Anton A S Date: Fri, 13 Mar 2026 14:54:12 +0300 Subject: [PATCH] Guard set_layout on NONE frames, remove implicit auto-layout on childCount >= 2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - set_layout returns error if direction omitted on layoutMode: NONE frame - Remove shouldEnableAutoLayout childCount >= 2 heuristic — require explicit flex prop --- packages/core/src/render/renderer.ts | 17 ++++++----------- packages/core/src/tools/modify.ts | 5 +++++ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/core/src/render/renderer.ts b/packages/core/src/render/renderer.ts index e0afcfc52..a94e9c32c 100644 --- a/packages/core/src/render/renderer.ts +++ b/packages/core/src/render/renderer.ts @@ -140,8 +140,7 @@ async function renderNode(graph: SceneGraph, tree: TreeNode, parentId: string): const parentLayout = parent?.layoutMode ?? 'NONE' const isText = nodeType === 'TEXT' - const childCount = tree.children.filter((c) => typeof c !== 'string' && isTreeNode(c)).length - const overrides = propsToOverrides(tree.props, isText, parentLayout, childCount) + const overrides = propsToOverrides(tree.props, isText, parentLayout) if (isText) { const textContent = tree.children.filter((c): c is string => typeof c === 'string').join('') @@ -356,12 +355,10 @@ function applyAutoLayoutSizing( function shouldEnableAutoLayout( props: Record, - isText: boolean, - childCount: number + isText: boolean ): boolean { if (props.flex !== undefined) return true if (!isText && hasAutoLayoutTriggerProps(props)) return true - if (!isText && !props.grid && childCount >= 2) return true return false } @@ -371,8 +368,7 @@ function applyLayoutOverrides( w: unknown, h: unknown, isText: boolean, - parentLayout: SceneNode['layoutMode'], - childCount: number + parentLayout: SceneNode['layoutMode'] ): void { if (props.grid) { applyGridOverrides(props, o, w, h) @@ -385,7 +381,7 @@ function applyLayoutOverrides( applyGridChildOverrides(props, o) } - if (shouldEnableAutoLayout(props, isText, childCount)) { + if (shouldEnableAutoLayout(props, isText)) { applyAutoLayoutSizing(o, props, w, h) } @@ -519,8 +515,7 @@ function applyShapeAndEffectOverrides(props: Record, o: Partial function propsToOverrides( props: Record, isText: boolean, - parentLayout: SceneNode['layoutMode'], - childCount = 0 + parentLayout: SceneNode['layoutMode'] ): Partial { const o: Partial = {} @@ -528,7 +523,7 @@ function propsToOverrides( const { w, h } = applySizeOverrides(props, o, parentLayout) applyVisualOverrides(props, o) - applyLayoutOverrides(props, o, w, h, isText, parentLayout, childCount) + applyLayoutOverrides(props, o, w, h, isText, parentLayout) if (isText) applyTextOverrides(props, o, parentLayout) applyShapeAndEffectOverrides(props, o) diff --git a/packages/core/src/tools/modify.ts b/packages/core/src/tools/modify.ts index 38240d8e0..8313fa33d 100644 --- a/packages/core/src/tools/modify.ts +++ b/packages/core/src/tools/modify.ts @@ -194,6 +194,11 @@ export const setLayout = defineTool({ const node = figma.getNodeById(args.id) if (!node) return { error: `Node "${args.id}" not found` } + const raw = figma.graph.getNode(args.id) + if (!args.direction && raw?.layoutMode === 'NONE') { + return { error: 'Frame has no auto-layout. Pass direction ("HORIZONTAL" or "VERTICAL") to enable it.' } + } + if (args.direction) node.layoutMode = args.direction as 'HORIZONTAL' | 'VERTICAL' if (args.spacing !== undefined) node.itemSpacing = args.spacing if (args.align !== undefined) node.primaryAxisAlignItems = args.align