Skip to content

Commit 2376266

Browse files
committed
Fix position
1 parent 51ea5b0 commit 2376266

File tree

8 files changed

+539
-21
lines changed

8 files changed

+539
-21
lines changed

src/__tests__/code.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,3 +185,32 @@ it('auto-runs on module load when figma is present', async () => {
185185

186186
expect(codegenOn).toHaveBeenCalledWith('generate', expect.any(Function))
187187
})
188+
189+
describe('extractImports', () => {
190+
it('should extract keyframes import when code contains keyframes(', () => {
191+
const result = codeModule.extractImports([
192+
[
193+
'AnimatedBox',
194+
'<Box animationName={keyframes({ "0%": { opacity: 0 } })} />',
195+
],
196+
])
197+
expect(result).toContain('keyframes')
198+
expect(result).toContain('Box')
199+
})
200+
201+
it('should extract keyframes import when code contains keyframes`', () => {
202+
const result = codeModule.extractImports([
203+
['AnimatedBox', '<Box animationName={keyframes`from { opacity: 0 }`} />'],
204+
])
205+
expect(result).toContain('keyframes')
206+
expect(result).toContain('Box')
207+
})
208+
209+
it('should not extract keyframes when not present', () => {
210+
const result = codeModule.extractImports([
211+
['SimpleBox', '<Box w="100px" />'],
212+
])
213+
expect(result).not.toContain('keyframes')
214+
expect(result).toContain('Box')
215+
})
216+
})

src/code-impl.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { exportDevup, importDevup } from './commands/devup'
44
import { exportAssets } from './commands/exportAssets'
55
import { exportComponents } from './commands/exportComponents'
66

7-
function extractImports(
7+
export function extractImports(
88
componentsCodes: ReadonlyArray<readonly [string, string]>,
99
): string[] {
1010
const allCode = componentsCodes.map(([_, code]) => code).join('\n')

src/codegen/__tests__/codegen.test.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4148,4 +4148,39 @@ describe('Codegen Tree Methods', () => {
41484148
expect(result).toContain('<MyButton')
41494149
})
41504150
})
4151+
4152+
describe('getSelectorProps with numeric property names', () => {
4153+
test('sanitizes property name that is only digits', async () => {
4154+
const defaultVariant = {
4155+
type: 'COMPONENT',
4156+
name: '123=Default',
4157+
children: [],
4158+
visible: true,
4159+
reactions: [],
4160+
variantProperties: { '123': 'Default' },
4161+
} as unknown as ComponentNode
4162+
4163+
const node = {
4164+
type: 'COMPONENT_SET',
4165+
name: 'NumericPropertySet',
4166+
children: [defaultVariant],
4167+
defaultVariant,
4168+
visible: true,
4169+
componentPropertyDefinitions: {
4170+
'123': {
4171+
type: 'VARIANT',
4172+
variantOptions: ['Default', 'Active'],
4173+
},
4174+
},
4175+
} as unknown as ComponentSetNode
4176+
addParent(node)
4177+
4178+
const codegen = new Codegen(node)
4179+
await codegen.buildTree()
4180+
4181+
// The numeric property name should be sanitized to 'variant'
4182+
const componentTrees = codegen.getComponentTrees()
4183+
expect(componentTrees.size).toBeGreaterThan(0)
4184+
})
4185+
})
41514186
})

src/codegen/props/__tests__/position.test.ts

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,13 @@ describe('position', () => {
1414
expect(canBeAbsolute(node)).toBe(true)
1515
})
1616

17-
it('should return true for AUTO positioned node in freelayout parent', () => {
17+
it('should return true for AUTO positioned node in freelayout parent with constraints', () => {
1818
const node = {
1919
layoutPositioning: 'AUTO',
20+
constraints: {
21+
horizontal: 'MIN',
22+
vertical: 'MIN',
23+
},
2024
parent: {
2125
layoutPositioning: 'AUTO',
2226
width: 100,
@@ -28,6 +32,20 @@ describe('position', () => {
2832
expect(canBeAbsolute(node)).toBe(true)
2933
})
3034

35+
it('should return false for AUTO positioned node in freelayout parent without constraints', () => {
36+
const node = {
37+
layoutPositioning: 'AUTO',
38+
parent: {
39+
layoutPositioning: 'AUTO',
40+
width: 100,
41+
height: 100,
42+
type: 'FRAME',
43+
},
44+
} as any
45+
46+
expect(canBeAbsolute(node)).toBe(false)
47+
})
48+
3149
it('should return false for node without parent', () => {
3250
const node = {
3351
layoutPositioning: 'ABSOLUTE',
@@ -67,13 +85,63 @@ describe('position', () => {
6785
})
6886
})
6987

70-
it('should return absolute position props without constraints in freelayout', () => {
88+
it('should return absolute position props in freelayout using fallback x/y', () => {
7189
const node = {
7290
layoutPositioning: 'AUTO',
7391
x: 15,
7492
y: 25,
7593
width: 40,
7694
height: 50,
95+
constraints: {
96+
horizontal: 'MIN',
97+
vertical: 'MIN',
98+
},
99+
parent: {
100+
layoutPositioning: 'AUTO',
101+
type: 'FRAME',
102+
width: 200,
103+
height: 300,
104+
},
105+
} as any
106+
107+
const result = getPositionProps(node)
108+
109+
expect(result).toEqual({
110+
pos: 'absolute',
111+
left: '15px',
112+
right: undefined,
113+
top: '25px',
114+
bottom: undefined,
115+
})
116+
})
117+
118+
it('should return undefined when no constraints in freelayout and canBeAbsolute is false', () => {
119+
const node = {
120+
layoutPositioning: 'AUTO',
121+
x: 15,
122+
y: 25,
123+
width: 40,
124+
height: 50,
125+
parent: {
126+
layoutPositioning: 'AUTO',
127+
type: 'FRAME',
128+
width: 200,
129+
height: 300,
130+
},
131+
} as any
132+
133+
const result = getPositionProps(node)
134+
135+
expect(result).toBeUndefined()
136+
})
137+
138+
it('should return absolute position with x/y when ABSOLUTE node has no constraints in freelayout parent', () => {
139+
const node = {
140+
layoutPositioning: 'ABSOLUTE',
141+
x: 15,
142+
y: 25,
143+
width: 40,
144+
height: 50,
77145
parent: {
78146
layoutPositioning: 'AUTO',
79147
type: 'FRAME',

0 commit comments

Comments
 (0)