fix(fig): preserve independent bound padding
- Treat leading-edge variable bindings as independent padding values - Serialize trailing padding when raw layout metadata would collapse it
This commit is contained in:
parent
b61957dff9
commit
072c159fdb
|
|
@ -423,14 +423,25 @@ function convertTextProps(nc: NodeChange, blobs: Uint8Array[]): TextProps {
|
|||
}
|
||||
}
|
||||
|
||||
function consumesVariableField(nc: NodeChange, field: string): boolean {
|
||||
return nc.variableConsumptionMap?.entries?.some((entry) => entry.variableField === field) ?? false
|
||||
}
|
||||
|
||||
function convertLayoutPadding(
|
||||
nc: NodeChange
|
||||
): Pick<SceneNode, 'paddingTop' | 'paddingBottom' | 'paddingLeft' | 'paddingRight'> {
|
||||
const basePadding = nc.stackPadding ?? 0
|
||||
const verticalPadding = nc.stackVerticalPadding ?? basePadding
|
||||
const horizontalPadding = nc.stackHorizontalPadding ?? basePadding
|
||||
return {
|
||||
paddingTop: nc.stackVerticalPadding ?? nc.stackPadding ?? 0,
|
||||
paddingBottom: nc.stackPaddingBottom ?? nc.stackVerticalPadding ?? nc.stackPadding ?? 0,
|
||||
paddingLeft: nc.stackHorizontalPadding ?? nc.stackPadding ?? 0,
|
||||
paddingRight: nc.stackPaddingRight ?? nc.stackHorizontalPadding ?? nc.stackPadding ?? 0
|
||||
paddingTop: verticalPadding,
|
||||
paddingBottom:
|
||||
nc.stackPaddingBottom ??
|
||||
(consumesVariableField(nc, 'STACK_PADDING_TOP') ? basePadding : verticalPadding),
|
||||
paddingLeft: horizontalPadding,
|
||||
paddingRight:
|
||||
nc.stackPaddingRight ??
|
||||
(consumesVariableField(nc, 'STACK_PADDING_LEFT') ? basePadding : horizontalPadding)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -305,6 +305,17 @@ function normalizeStackCounterAlign(value: string | undefined): string | undefin
|
|||
return value === 'SPACE_EVENLY' ? 'SPACE_BETWEEN' : value
|
||||
}
|
||||
|
||||
function preserveTrailingPadding(
|
||||
explicitValue: number | undefined,
|
||||
leadingValue: number | undefined,
|
||||
baseValue: number | undefined,
|
||||
normalizedValue: number
|
||||
): number | undefined {
|
||||
if (explicitValue !== undefined) return explicitValue
|
||||
const inheritedValue = leadingValue ?? baseValue ?? normalizedValue
|
||||
return normalizedValue !== inheritedValue ? normalizedValue : undefined
|
||||
}
|
||||
|
||||
function serializeLayoutProps(node: SceneNode, nc: KiwiNodeChange): void {
|
||||
if (!node.source.id) upsertPluginData(node, LAYOUT_DIRECTION_PLUGIN_KEY, node.layoutDirection)
|
||||
const figLayout = node.source.fig.layout
|
||||
|
|
@ -312,8 +323,18 @@ function serializeLayoutProps(node: SceneNode, nc: KiwiNodeChange): void {
|
|||
nc.stackMode = normalizeStackMode(figLayout.stackMode)
|
||||
nc.stackSpacing = figLayout.stackSpacing
|
||||
nc.stackPadding = figLayout.stackPadding
|
||||
nc.stackPaddingRight = figLayout.stackPaddingRight
|
||||
nc.stackPaddingBottom = figLayout.stackPaddingBottom
|
||||
nc.stackPaddingRight = preserveTrailingPadding(
|
||||
figLayout.stackPaddingRight,
|
||||
figLayout.stackHorizontalPadding,
|
||||
figLayout.stackPadding,
|
||||
node.paddingRight
|
||||
)
|
||||
nc.stackPaddingBottom = preserveTrailingPadding(
|
||||
figLayout.stackPaddingBottom,
|
||||
figLayout.stackVerticalPadding,
|
||||
figLayout.stackPadding,
|
||||
node.paddingBottom
|
||||
)
|
||||
nc.stackCounterAlign = normalizeStackCounterAlign(figLayout.stackCounterAlign)
|
||||
nc.stackJustify = normalizeStackJustify(figLayout.stackJustify)
|
||||
nc.stackCounterAlignItems = normalizeStackCounterAlign(figLayout.stackCounterAlignItems)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,44 @@
|
|||
import { describe, expect, test } from 'bun:test'
|
||||
|
||||
import { importNodeChanges } from '@open-pencil/core'
|
||||
import { nodeChangeToProps } from '@open-pencil/fig/node-change'
|
||||
import type { NodeChange } from '@open-pencil/kiwi/fig/codec'
|
||||
|
||||
import { canvas, doc, node } from '../helpers'
|
||||
|
||||
describe('fig-import: auto-layout alignment', () => {
|
||||
test('keeps variable-bound leading padding independent', () => {
|
||||
const props = nodeChangeToProps(
|
||||
{
|
||||
type: 'FRAME',
|
||||
stackMode: 'VERTICAL',
|
||||
stackVerticalPadding: 8,
|
||||
stackHorizontalPadding: 6,
|
||||
variableConsumptionMap: {
|
||||
entries: [
|
||||
{
|
||||
variableField: 'STACK_PADDING_TOP',
|
||||
variableData: {
|
||||
value: { alias: { guid: { sessionID: 2, localID: 1 } } }
|
||||
}
|
||||
},
|
||||
{
|
||||
variableField: 'STACK_PADDING_LEFT',
|
||||
variableData: {
|
||||
value: { alias: { guid: { sessionID: 2, localID: 2 } } }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
} as NodeChange,
|
||||
[]
|
||||
)
|
||||
expect(props.paddingTop).toBe(8)
|
||||
expect(props.paddingBottom).toBe(0)
|
||||
expect(props.paddingLeft).toBe(6)
|
||||
expect(props.paddingRight).toBe(0)
|
||||
})
|
||||
|
||||
test('maps SPACE_EVENLY kiwi primary alignment to Figma space-between', () => {
|
||||
const graph = importNodeChanges([
|
||||
doc(),
|
||||
|
|
|
|||
|
|
@ -64,8 +64,8 @@ const SPECS: FixtureSpec[] = [
|
|||
thumbnailHeight: 239,
|
||||
imageCount: 3,
|
||||
figKiwiVersion: 101,
|
||||
g1ExportSize: 596988,
|
||||
g2ExportSize: 596988
|
||||
g1ExportSize: 596992,
|
||||
g2ExportSize: 596992
|
||||
}
|
||||
]
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue