-
-
Notifications
You must be signed in to change notification settings - Fork 219
fix incomplete theme application issue #3756
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,4 +12,5 @@ export const ValidNodeTypes: NodeType[] = [ | |
| 'TEXT', | ||
| 'VECTOR', | ||
| 'STAR', | ||
| 'SECTION', | ||
| ]; | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,23 +1,40 @@ | ||||||||||||||||||||||||||||||||||||||||||
| import { ValidNodeTypes } from '@/constants/ValidNodeTypes'; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| export function findAll(nodes: readonly BaseNode[], includeSelf = false, nodesWithoutPluginData = false): BaseNode[] { | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
| let allNodes = includeSelf ? [...nodes] : []; | ||||||||||||||||||||||||||||||||||||||||||
| const pluginDataOptions = nodesWithoutPluginData | ||||||||||||||||||||||||||||||||||||||||||
| ? {} | ||||||||||||||||||||||||||||||||||||||||||
| : { | ||||||||||||||||||||||||||||||||||||||||||
| sharedPluginData: { | ||||||||||||||||||||||||||||||||||||||||||
| namespace: 'tokens', | ||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||
| const allNodesSet = new Set<BaseNode>(includeSelf ? nodes : []); | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| nodes.forEach((node) => { | ||||||||||||||||||||||||||||||||||||||||||
| if ('children' in node) { | ||||||||||||||||||||||||||||||||||||||||||
| allNodes = allNodes.concat( | ||||||||||||||||||||||||||||||||||||||||||
| if (nodesWithoutPluginData) { | ||||||||||||||||||||||||||||||||||||||||||
| // Smart Discovery: | ||||||||||||||||||||||||||||||||||||||||||
| // 1. Find all nodes with local token data (Figma optimized search) | ||||||||||||||||||||||||||||||||||||||||||
| const withLocalData = node.findAllWithCriteria({ | ||||||||||||||||||||||||||||||||||||||||||
| types: ValidNodeTypes, | ||||||||||||||||||||||||||||||||||||||||||
| sharedPluginData: { namespace: 'tokens' }, | ||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||
| withLocalData.forEach(n => allNodesSet.add(n)); | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| // 2. Find all instances (their children have inherited token data) | ||||||||||||||||||||||||||||||||||||||||||
| const instances = node.findAllWithCriteria({ | ||||||||||||||||||||||||||||||||||||||||||
| types: ['INSTANCE'], | ||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||
| instances.forEach(instance => { | ||||||||||||||||||||||||||||||||||||||||||
| allNodesSet.add(instance); | ||||||||||||||||||||||||||||||||||||||||||
| // For each instance, we must also check all its children | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+17
to
+23
|
||||||||||||||||||||||||||||||||||||||||||
| // 2. Find all instances (their children have inherited token data) | |
| const instances = node.findAllWithCriteria({ | |
| types: ['INSTANCE'], | |
| }); | |
| instances.forEach(instance => { | |
| allNodesSet.add(instance); | |
| // For each instance, we must also check all its children | |
| // 2. Find all instances (their children may have inherited token data) | |
| const instances = node.findAllWithCriteria({ | |
| types: ['INSTANCE'], | |
| }); | |
| instances.forEach(instance => { | |
| allNodesSet.add(instance); | |
| // IMPORTANT: | |
| // We intentionally search *all* children of instances, without filtering | |
| // by shared plugin data here. Children can inherit token data from their | |
| // parent component and therefore may not have any local plugin data set. | |
| // These nodes are later filtered in NodeManager based on actual token data. | |
| // Narrowing this search (e.g. by sharedPluginData) would cause us to miss | |
| // inherited tokens on instance children. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This refactoring changes the iteration logic from checking only the keys present on the node to checking all possible Properties enum values. While this ensures all known properties are checked (which may help with the incomplete theme application issue), it's less efficient as it makes up to 61 getSharedPluginData calls per node instead of only checking existing keys. Consider documenting why this change was necessary for fixing the theme application issue, as it's a significant performance trade-off.