Hi @Jeroen2, Thank you for reaching out and sharing your design file with us. I appreciate it!
I just want to make sure I’m understanding correctly - do you override the variant property value for the nested button-component at the main component level?
If so, based on some internal exploration and testing on my end, unfortunately, it appears that if you perform a swap at the component level, instances of those components do not preserve overrides.
Figma only preserves overrides on instances when swaps are performed within that instance.
I hope this information helps clarify things a bit. If there’s anything I’ve misunderstood, please let us know.
Thanks,
Thank you Junko3 for taking some time to understand the situation. In the document I referenced above, I created an example-frame which contains instances of the popover-button component. What follows is quite a detailed analysis. Please bear with me.
Each of the popover-button components displayed here is an instance of the main component.
- “original” has no variant overrides.
- “white” has the button color variant overriden to “white”.
- “danger” has the button color variant overridden to “danger”
- “success” has the button color variant overridden to “success”
⚠️ Important note #1
It is important to note that the nested button-component has another component nested into it, called “interactivity background”. This interactivity background has color variants that match the button color variants.
To create interactive states (hover/active) The interactivity background has additional variants for this: “state” with values “idle”, “hover” and “active”.
⚠️ important note #2
Additionally, it is good to know that the variant-property “opened” is used to control the open/close state, including the button interactive state (idle to active)
I notice that the unexpected behavior is bifold: I see behaviors differ in design mode and in prototype mode
1. In design mode
In design mode, switching the popover-component to another variant preserves the override on the direct “child component”, but not on any successively nested “child-in-child components”. In my example it seems like for children-in-children, their original variant overrides are discarded, even if in the main component where they are nested they had an override. Allow me to elaborate.
Situation |
Visual result |
---|
step 0: without any variants toggled |
|
step 1: toggle opened/closed first time |
|
step 2: toggle opened/closed second time, back to initial open/close state. |
|
Because of this, I wanted to try out what was going on with the “child-in-child” interactivity background component. Hence, the default interactivity background for the button color variant in the main component of “popover button” is now red:
This is the same situation as in the first image, but then with the “original” button with a read active state. For clarity, I used some other color instead of “danger”. Let’s repeat the scenario above!
Situation |
Visual result |
---|
step 0: no variant switch |
|
step 1: 1st time switch of variant: back to the default variant |
|
step 2: 2nd time switch of variant: revert to the variant before the first switch. |
|
As you can see, the color of “interactivity background” is not reverted to the color variant that was initially set for the overridden color variant of its parent component “button”, but rather to the color variant of the “un-overriden” button color variant for the parent-of-the-parent “popover button”.
It’s as if only shallow nested instances of components have their overrides preserved, not deep nested instances of components. But here we are entering the territory of recursion, which is inherently hard to wrap your head around. For me, it definitely is.
Brace yourself! As promised, there is another unexpected behavior… 😅
2. prototype mode
The popover-button component is set up to open/close upon click of the nested button. To ensure that all variant properties are correctly set for child components (and for children of children), the variant change upon click is set to reset component states. At least, that was my theory. On the flip side, not resetting component states at all results in variants of nested component instances not changing at all, which is also undesirable behavior.
This is what happens if I follow the same steps as above:
Situation |
Visual result |
---|
step 0: without any variants toggled |
|
step 1: toggle opened/closed first time |
|
step 2: toggle opened/closed second time, back to initial open/close state. |
|
It appears that during step 1 all overrides are reset. But during step 2, all overrides are reverted back.
So here’s the bifold:
Design mode |
Prototype mode |
---|
It’s as if only shallow nested instances of components have their overrides preserved, not deep nested instances of components. |
It appears that during step 1 all overrides are reset. But during step 2, all overrides are reverted back. |
As a result, I am not quite sure what to do.
- Is this something I can fix in the setup of my design system?
- Or is it something worth submitting a feature request for?
- Or… is it a bug that I should report?
Hi there, Thank you for providing those details. I truly appreciate you taking the time to share your setup and troubleshoot.
I recommend reaching out to our support team directly. They can closely examine your design file and provide direct support for each of your questions. Would you mind submitting a request from here?: https://help.figma.com/hc/en-us/requests/new
When contacting our support team, please make sure to provide the following information:
- Please use your Figma account email address.
- Share the direct links to the file in question and any related library files. Add support-share@figma.com as an Editor to those files (this won’t affect your billing)
Thank you for your assistance!
Thank you for your reply. I will follow up on this with the support team. In doing so, I will refer to the aforementioned troubleshooting as well. 👍
Done! I’ve created a support request. The following has been included:
- A reference to this forum thread.
- A reference to the aforementioned test file, with test cases.
Additionally, I have updated the aforementioned test file. Now it includes some more clarification on the problem statement, the approach for verifying the bifold issue, the document structure and my own test results.
@Jeroen2 Hey there, I’m having the exact same problem. It makes no sense for me to recreate every single child state on the parent component. Did you find a solution in the end? Also, I SWEAR this used to work at some point…???
I’m not sure if proper persistance of deep nested instances’ properties has ever worked. However, the above research has been shared with Figma Support in a support ticket. They confirmed the discrepancy based on my tests. Not sure what is the course of action from this point on, but engineers are being involved. The support ticket remains opened, so I am following as it unfolds.
I hope they fix this because the anger makes me want to stop using components… I would swear that in the past it has worked well… It happens with everything Figma do… They add new functionalities but are half-way implemented… Like the variables without math operations…
I hope one day they start using beta version and stop breaking our designs with every update 😕
Hi @Ivan_Perez, Thank you so much for sharing your feedback with us. We understand that you’re feeling like something isn’t working as it should.
The ticket that Jeroen2 kindly submitted is still open, and our engineering team is actively reviewing the case. This process may take some time.
If you would like our support team to look into your specific file, I would be more than happy to create a support ticket on your behalf. In this ticket, you can provide the files with editing access for our support team to examine closely. Please inform us if you would like us to go ahead and create a ticket for further assist.
Thanks,
Hi all, I lost track of this thread, so I would like to get back to it. In the meantime, there has been some correspondence back and forth with support and through support with engineering.
At this point, it is regarded intended behavior. On a technical level, what it boils down to, is this:
The loss of overrides for nested instances occurs as Figma’s process to perform the instance swap on the top level applies a new higher priority override which is expected to remove any overrides from an earlier instance swap on a lower level on any nested instances.
Consequently, higher-level property overrides will result in changes on lower-level instances being discarded.
A suggestion is to use Variables with modes for supporting variability, rather than component variants when nesting instances of components. Of course, earlier discussions on this forum suggest that the limitations regarding Variables do not make this suggestion any more practical. Support is aware of this. Another suggestion was to decouple component sets and not use deep nesting at all.
All I could do at that point was to stress the efficiency win in the workflow, should the nested instance property persistence be improved. And that is what I did; no nesting or shallow nesting results in having to maintain an exponential amount of components, while nesting would “trickle down” changes through inheritance. Also, relying on variable modes is not feasible. Variable modes are too restricted for this use case. What’s more, the inconsistency between Prototypes and the Design canvas is sub-optimal as-is.
This was the end of the conversation. There is not much perspective and neither any guarantees, but at least I was able to give input, which was passed on to the engineering team.
It never did. Figma’s whole rendering engine just isn’t performant enough.
Maybe if they had just reused HTML/CSS like PenPot instead of rebuilding everything themselves, they wouldn’t have such issues. But it’s too late for them.