-
-
Notifications
You must be signed in to change notification settings - Fork 189
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
allow for bulk remap with variable and styles #2405
base: main
Are you sure you want to change the base?
allow for bulk remap with variable and styles #2405
Conversation
🦋 Changeset detectedLatest commit: c376148 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
PR Analysis
PR Feedback
How to useInstructions
|
Commit SHA:8590c62eac168d3e1e3c794a9971027ad57cf333 Test coverage results 🧪
|
Commit SHA:8590c62eac168d3e1e3c794a9971027ad57cf333 |
const savedVariableData = node.getSharedPluginData(SharedPluginDataNamespaces.VARIABLES, variableType); | ||
if (savedVariableData.length > 0) { | ||
if (savedVariableData.includes(oldName)) { | ||
const newValue = JSON.parse(savedVariableData).replace(oldName, newName); | ||
const jsonValue = JSON.stringify(newValue); | ||
node.setSharedPluginData(SharedPluginDataNamespaces.VARIABLES, variableType, jsonValue); |
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.
I think this is a misunderstanding. We should not get or set variables on shared plugin data. Variables can be set directly using boundVariables and the other variable functions. Here you've applied shared plugin data for variables instead.
There's no need to do this. Let's just read what variables are applied on the layer (Inspect already shows this!), then take the names of those, remap parts of the name, and then find the connected variables to replace it with.
For example, if a variable named colors.blue.500 is applied, and another layer has colors.blue.400, and I remap 'blue' to 'red' then we'd need to
- look up tokens named 'colors.red.400'
- and 500 and fetch the connected variables
- replace the applied variables with those
const jsonValue = JSON.stringify(newValue); | ||
node.setSharedPluginData(SharedPluginDataNamespaces.STYLES, styleType, jsonValue); | ||
} | ||
} else if (styleName.includes(oldName)) { | ||
const newValue = styleName.replace(oldName, newName); | ||
const jsonValue = JSON.stringify(newValue); | ||
node.setSharedPluginData(SharedPluginDataNamespaces.STYLES, styleType, jsonValue); |
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.
Same for styles
…into 2120-allow-for-bulk-remapping-with-variables-styles
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.
can you also make sure to revert the SharedPluginDataNamespaces.STYLES
and SharedPluginDataNamespaces.VARIABLES
code? we dont need that now that you've reverted it
Also, a test case would be great.
const paint = figma.util.solidPaint(resolvedValue?.value as string); | ||
const fillsCopy = clone(node.fills); | ||
fillsCopy[0] = figma.variables.setBoundVariableForPaint(paint, 'color', variable); | ||
const newLocalVariable = getLocalVariableByName(resolvedValue?.name as string); |
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 will only work for local variables. In most cases, users don't have variables in the same file. Can you refactor this so it's fetching the variable by key (i think https://www.figma.com/plugin-docs/api/properties/figma-variables-importvariablebykeyasync/ should do the trick, we're using it elsewhere)
…into 2120-allow-for-bulk-remapping-with-variables-styles
return localVariables.find((variable) => variable.resolvedType === 'COLOR' && variable.name.split('/').join('.') === name); | ||
}; | ||
const getStyleByName = (name: string) => ( | ||
figma.getLocalPaintStyles().find((style) => style.name === name) |
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.
same for styles, users will not have those styles local, they will be remote. we need to fetch those from the remote.
@@ -50,7 +50,7 @@ export const bulkRemapTokens: AsyncMessageChannelHandlers[AsyncMessageTypes.BULK | |||
} | |||
}); | |||
|
|||
if (Object.keys(tokens).length > 0) { | |||
if (Object.keys(tokens).length === 0) { |
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.
is this on purpose? this would mean this would never run
@@ -63,13 +63,20 @@ export const bulkRemapTokens: AsyncMessageChannelHandlers[AsyncMessageTypes.BULK | |||
const paint = figma.util.solidPaint(resolvedValue?.value as string); | |||
const fillsCopy = clone(node.fills); | |||
fillsCopy[0] = figma.variables.setBoundVariableForPaint(paint, 'color', variable); | |||
const newLocalVariable = getLocalVariableByName(resolvedValue?.name as string); | |||
fillsCopy[0].boundVariables.color.id = newLocalVariable?.id; | |||
const newVariable = await figma.variables.importVariableByKeyAsync(resolvedValue?.name as string); |
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.
have you tried if it's faster if you store these in a cache? i assume if a user has 100 variables applied and remaps them, with this current approach we call importVariableByKeyAsync
100 times. if we had it in store we would call it 1 time.
if (getAppliedStylesFromNode(node).length > 0) { | ||
const { name: styleName } = getAppliedStylesFromNode(node)[0]; | ||
if (node.type !== 'DOCUMENT' && node.type !== 'PAGE' && 'fills' in node) { | ||
const newStyle = getStyleByName(styleName.replace(oldName, newName).split('.').join('/')); |
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.
as mentioned above, this currently will just work for local styles. users will likely almost never have these locally.
VARIABLES = 'variables', | ||
STYLES = 'styles', |
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.
not needed anymore
|
||
if (Object.keys(tokens).length === 0) { | ||
if (getAppliedVariablesFromNode(node).length > 0) { | ||
const { name: variableName } = getAppliedVariablesFromNode(node)[0]; |
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.
does this mean we only pick the first variable from all applied properties? what if there's a color, a width, a height, a spacing variable attached?
const effectStyles = figma.getLocalEffectStyles(); | ||
const paintStyles = figma.getLocalPaintStyles(); | ||
const textStyles = figma.getLocalTextStyles(); | ||
const allStyles = [...effectStyles, ...paintStyles, ...textStyles]; |
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 is something that happens on every token, and on every node now. move this code outside of the main function to just perform it once and then remember those
const textStyles = figma.getLocalTextStyles(); | ||
const allStyles = [...effectStyles, ...paintStyles, ...textStyles]; | ||
|
||
const themeInfo = await AsyncMessageChannel.PluginInstance.message({ |
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.
again, this happens on every node and on every token, this has got to be costly for performance. move it outside the main function and just trigger it once
No description provided.