@@ -3759,6 +3759,96 @@ describe('Codegen Tree Methods', () => {
37593759 expect(condChild?.condition).toBe('showIcon')
37603760 })
37613761
3762+ test('detects BOOLEAN conditions on nested grandchildren (not just direct children)', async () => {
3763+ // Grandchild INSTANCE nodes with componentPropertyReferences.visible
3764+ // These are inside a FRAME wrapper, not direct children of the COMPONENT
3765+ const subTitle1 = {
3766+ type: 'INSTANCE',
3767+ name: 'CurriculumSubTitle1',
3768+ visible: true,
3769+ componentPropertyReferences: { visible: '_1st#80:1' },
3770+ getMainComponentAsync: async () =>
3771+ ({
3772+ type: 'COMPONENT',
3773+ name: 'CurriculumSubTitle',
3774+ children: [],
3775+ visible: true,
3776+ }) as unknown as ComponentNode,
3777+ } as unknown as InstanceNode
3778+
3779+ const subTitle2 = {
3780+ type: 'INSTANCE',
3781+ name: 'CurriculumSubTitle2',
3782+ visible: true,
3783+ componentPropertyReferences: { visible: '_2nd#80:2' },
3784+ getMainComponentAsync: async () =>
3785+ ({
3786+ type: 'COMPONENT',
3787+ name: 'CurriculumSubTitle',
3788+ children: [],
3789+ visible: true,
3790+ }) as unknown as ComponentNode,
3791+ } as unknown as InstanceNode
3792+
3793+ // Intermediate wrapper frame — this is the direct child of the COMPONENT
3794+ const contentWrapper = {
3795+ type: 'FRAME',
3796+ name: 'ContentWrapper',
3797+ children: [subTitle1, subTitle2],
3798+ visible: true,
3799+ strokes: [],
3800+ effects: [],
3801+ reactions: [],
3802+ } as unknown as FrameNode
3803+
3804+ const defaultVariant = {
3805+ type: 'COMPONENT',
3806+ name: 'State=Default',
3807+ children: [contentWrapper],
3808+ visible: true,
3809+ reactions: [],
3810+ } as unknown as ComponentNode
3811+
3812+ const node = {
3813+ type: 'COMPONENT_SET',
3814+ name: 'CurriculumCard',
3815+ children: [defaultVariant],
3816+ defaultVariant,
3817+ visible: true,
3818+ componentPropertyDefinitions: {
3819+ '_1st#80:1': {
3820+ type: 'BOOLEAN',
3821+ defaultValue: true,
3822+ },
3823+ '_2nd#80:2': {
3824+ type: 'BOOLEAN',
3825+ defaultValue: true,
3826+ },
3827+ },
3828+ } as unknown as ComponentSetNode
3829+ addParent(node)
3830+
3831+ const codegen = new Codegen(node)
3832+ await codegen.buildTree()
3833+
3834+ const componentTrees = codegen.getComponentTrees()
3835+ const compTree = [...componentTrees.values()].find(
3836+ (ct) => ct.name === 'CurriculumCard',
3837+ )
3838+ expect(compTree).toBeDefined()
3839+
3840+ // The direct child (ContentWrapper) should NOT have a condition
3841+ const wrapper = compTree?.tree.children[0]
3842+ expect(wrapper?.condition).toBeUndefined()
3843+
3844+ // The grandchildren (inside ContentWrapper) SHOULD have conditions
3845+ const grandchildren = wrapper?.children ?? []
3846+ const cond1 = grandchildren.find((c) => c.condition === '_1st')
3847+ const cond2 = grandchildren.find((c) => c.condition === '_2nd')
3848+ expect(cond1).toBeDefined()
3849+ expect(cond2).toBeDefined()
3850+ })
3851+
37623852 test('detects combined INSTANCE_SWAP + BOOLEAN slot with condition', async () => {
37633853 const iconChild = {
37643854 type: 'INSTANCE',
@@ -4196,6 +4286,80 @@ describe('Codegen Tree Methods', () => {
41964286 }
41974287 })
41984288
4289+ test('renders component with nested BOOLEAN conditionals (grandchildren)', async () => {
4290+ const subTitle1 = {
4291+ type: 'INSTANCE',
4292+ name: 'CurriculumSubTitle1',
4293+ visible: true,
4294+ componentPropertyReferences: { visible: '_1st#80:1' },
4295+ getMainComponentAsync: async () =>
4296+ ({
4297+ type: 'COMPONENT',
4298+ name: 'CurriculumSubTitle',
4299+ children: [],
4300+ visible: true,
4301+ }) as unknown as ComponentNode,
4302+ } as unknown as InstanceNode
4303+
4304+ const subTitle2 = {
4305+ type: 'INSTANCE',
4306+ name: 'CurriculumSubTitle2',
4307+ visible: true,
4308+ componentPropertyReferences: { visible: '_2nd#80:2' },
4309+ getMainComponentAsync: async () =>
4310+ ({
4311+ type: 'COMPONENT',
4312+ name: 'CurriculumSubTitle',
4313+ children: [],
4314+ visible: true,
4315+ }) as unknown as ComponentNode,
4316+ } as unknown as InstanceNode
4317+
4318+ const contentWrapper = {
4319+ type: 'FRAME',
4320+ name: 'ContentWrapper',
4321+ children: [subTitle1, subTitle2],
4322+ visible: true,
4323+ strokes: [],
4324+ effects: [],
4325+ reactions: [],
4326+ } as unknown as FrameNode
4327+
4328+ const defaultVariant = {
4329+ type: 'COMPONENT',
4330+ name: 'State=Default',
4331+ children: [contentWrapper],
4332+ visible: true,
4333+ reactions: [],
4334+ } as unknown as ComponentNode
4335+
4336+ const node = {
4337+ type: 'COMPONENT_SET',
4338+ name: 'CurriculumCard',
4339+ children: [defaultVariant],
4340+ defaultVariant,
4341+ visible: true,
4342+ componentPropertyDefinitions: {
4343+ '_1st#80:1': {
4344+ type: 'BOOLEAN',
4345+ defaultValue: true,
4346+ },
4347+ '_2nd#80:2': {
4348+ type: 'BOOLEAN',
4349+ defaultValue: true,
4350+ },
4351+ },
4352+ } as unknown as ComponentSetNode
4353+ addParent(node)
4354+
4355+ const codegen = new Codegen(node)
4356+ await codegen.run()
4357+
4358+ for (const [name, code] of codegen.getComponentsCodes()) {
4359+ expect(code).toMatchSnapshot(`nested BOOLEAN conditional: ${name}`)
4360+ }
4361+ })
4362+
41994363 test('renders component with INSTANCE_SWAP + BOOLEAN combined', async () => {
42004364 const leftIconChild = {
42014365 type: 'INSTANCE',
0 commit comments