Skip to content
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

Open
wants to merge 22 commits into
base: main
Choose a base branch
from

Conversation

robinhoodie0823
Copy link
Contributor

No description provided.

Copy link

changeset-bot bot commented Dec 4, 2023

🦋 Changeset detected

Latest commit: c376148

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@tokens-studio/figma-plugin Patch

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

Copy link
Contributor

github-actions bot commented Dec 4, 2023

PR Analysis

  • 🎯 Main theme: The main theme of this PR is to allow bulk remapping with variables and styles in the application.
  • 📝 PR summary: This PR introduces the ability to perform bulk remapping with variables and styles. It includes changes in several files to handle the new functionality. The changes involve adding new variables and styles, updating the NodeManager class, and modifying the bulkRemapTokens function.
  • 📌 Type of PR: Enhancement
  • 🧪 Relevant tests added: No
  • ⏱️ Estimated effort to review [1-5]: 4, because the PR involves changes in multiple files and introduces new functionality, which requires a good understanding of the existing codebase to review effectively.
  • 🔒 Security concerns: No security concerns found

PR Feedback

How to use

Instructions

To invoke the PR-Agent, add a comment using one of the following commands:
/review: Request a review of your Pull Request.
/describe: Update the PR title and description based on the contents of the PR.
/improve [--extended]: Suggest code improvements. Extended mode provides a higher quality feedback.
/ask <QUESTION>: Ask a question about the PR.
/update_changelog: Update the changelog based on the PR's contents.
/add_docs: Generate docstring for new components introduced in the PR.
/generate_labels: Generate labels for the PR based on the PR's contents.
see the tools guide for more details.

To edit any configuration parameter from the configuration.toml, add --config_path=new_value.
For example: /review --pr_reviewer.extra_instructions="focus on the file: ..."
To list the possible configuration parameters, add a /config comment.

Copy link
Contributor

github-actions bot commented Dec 4, 2023

Commit SHA:8590c62eac168d3e1e3c794a9971027ad57cf333

Test coverage results 🧪

Code coverage diff between base branch:main and head branch: 2120-allow-for-bulk-remapping-with-variables-styles 
Status File % Stmts % Branch % Funcs % Lines
🔴 total 70.45 (-0.23) 60.68 (-0.28) 68.61 (-0.26) 70.71 (-0.22)
🔴 src/plugin/asyncMessageHandlers/bulkRemapTokens.ts 45.2 (-50.03) 9.09 (-90.91) 28.57 (-71.43) 47.14 (-48.09)

Copy link
Contributor

github-actions bot commented Dec 4, 2023

Commit SHA:8590c62eac168d3e1e3c794a9971027ad57cf333
Current PR reduces the test coverage percentage by 100 for some tests

@robinhoodie0823 robinhoodie0823 self-assigned this Dec 4, 2023
@robinhoodie0823 robinhoodie0823 linked an issue Dec 4, 2023 that may be closed by this pull request
.changeset/unlucky-forks-mate.md Outdated Show resolved Hide resolved
src/app/components/InspectorTokenSingle.tsx Show resolved Hide resolved
Comment on lines 47 to 52
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);
Copy link
Collaborator

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

Comment on lines 69 to 75
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);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for styles

Copy link
Collaborator

@six7 six7 left a 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.

package.json Outdated Show resolved Hide resolved
package.json Outdated Show resolved Hide resolved
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);
Copy link
Collaborator

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)

return localVariables.find((variable) => variable.resolvedType === 'COLOR' && variable.name.split('/').join('.') === name);
};
const getStyleByName = (name: string) => (
figma.getLocalPaintStyles().find((style) => style.name === name)
Copy link
Collaborator

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) {
Copy link
Collaborator

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);
Copy link
Collaborator

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('/'));
Copy link
Collaborator

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.

Comment on lines 3 to 4
VARIABLES = 'variables',
STYLES = 'styles',
Copy link
Collaborator

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];
Copy link
Collaborator

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?

Comment on lines 78 to 81
const effectStyles = figma.getLocalEffectStyles();
const paintStyles = figma.getLocalPaintStyles();
const textStyles = figma.getLocalTextStyles();
const allStyles = [...effectStyles, ...paintStyles, ...textStyles];
Copy link
Collaborator

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({
Copy link
Collaborator

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow For Bulk Remapping With Variables & Styles
3 participants