From 6e20bcb3163c5392672e07035b6f98ebf04a235a Mon Sep 17 00:00:00 2001 From: Matthew Ratzke Date: Fri, 19 Jan 2024 18:22:13 -0700 Subject: [PATCH 1/4] [fix] update variable values to include name conversion --- src/transformer/standardTransformer.ts | 7 ++++--- src/utilities/changeNotation.ts | 6 ++++-- src/utilities/getVariables.ts | 6 +++--- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/transformer/standardTransformer.ts b/src/transformer/standardTransformer.ts index ffbf2f86..d15eef6b 100644 --- a/src/transformer/standardTransformer.ts +++ b/src/transformer/standardTransformer.ts @@ -5,6 +5,7 @@ import roundWithDecimals from '../utilities/roundWithDecimals' import { tokenExtensions } from './tokenExtensions' import config from '@config/config' import { changeNotation } from '@src/utilities/changeNotation' +import { Settings } from '../../types/settings' const lineHeightToDimension = (values): number => { if (values.lineHeight.unit === 'pixel') { @@ -257,13 +258,13 @@ const valueTransformer = { opacity: opacityValueTransformer } -const transformVariable = ({ values, category }): StandardTokenDataInterface => { +const transformVariable = ({ values, category }, settings: Settings): StandardTokenDataInterface => { const refRegEx = /^{[^{}]*}$/ // is alias if (refRegEx.test(values)) { return { type: category as StandardTokenTypes, - value: changeNotation(values, '/', '.') + value: changeNotation(values, '/', '.', settings.nameConversion) } } if (category === 'color') { @@ -297,7 +298,7 @@ const transformer = (token: internalTokenInterface, settings): StandardTokenInte return { name: token.name, description: token.description, - ...transformVariable(token), + ...transformVariable(token, settings), ...tokenExtensions(token, settings) } } diff --git a/src/utilities/changeNotation.ts b/src/utilities/changeNotation.ts index a5c7ba1d..90417a34 100644 --- a/src/utilities/changeNotation.ts +++ b/src/utilities/changeNotation.ts @@ -1,3 +1,5 @@ -export const changeNotation = (name, currentDelimiter = '/', desiredDelimiter = '.') => { - return name.split(currentDelimiter).join(desiredDelimiter).toLowerCase() +import transformName from './transformName' + +export const changeNotation = (name: string, currentDelimiter = '/', desiredDelimiter = '.', nameConversion: string = 'default') => { + return name.split(currentDelimiter).map(group => transformName(group, nameConversion)).join(desiredDelimiter).toLowerCase() } diff --git a/src/utilities/getVariables.ts b/src/utilities/getVariables.ts index ba6bd887..3a1cd893 100644 --- a/src/utilities/getVariables.ts +++ b/src/utilities/getVariables.ts @@ -9,7 +9,7 @@ import { getVariableTypeByValue } from './getVariableTypeByValue' import roundWithDecimals from './roundWithDecimals' import { Settings } from '@typings/settings' -const extractVariable = (variable, value) => { +const extractVariable = (variable, value, settings: Settings) => { let category: tokenCategoryType = 'color' let values = {} if (value.type === 'VARIABLE_ALIAS') { @@ -20,7 +20,7 @@ const extractVariable = (variable, value) => { description: variable.description || undefined, exportKey: tokenTypes.variables.key as tokenExportKeyType, category: getVariableTypeByValue(Object.values(resolvedAlias.valuesByMode)[0]), - values: `{${collection.name.toLowerCase()}.${changeNotation(resolvedAlias.name, '/', '.')}}`, + values: `{${collection.name.toLowerCase()}.${changeNotation(resolvedAlias.name, '/', '.', settings.nameConversion)}}`, // this is being stored so we can properly update the design tokens later to account for all // modes when using aliases @@ -101,7 +101,7 @@ export const getVariables = (figma: PluginAPI, settings: Settings) => { // Only add mode if there's more than one let addMode = settings.modeReference && modes.length > 1 return { - ...extractVariable(variable, value), + ...extractVariable(variable, value, settings), // name is contstructed from collection, mode and variable name name: addMode ? `${collection}/${modes.find(({ modeId }) => modeId === id).name}/${variable.name}` : `${collection}/${variable.name}`, From 992837cc534ab0a3a71e50d7932c3d8e66d910b8 Mon Sep 17 00:00:00 2001 From: Matthew Ratzke Date: Fri, 19 Jan 2024 18:31:52 -0700 Subject: [PATCH 2/4] update name conversion on collection name --- src/utilities/getVariables.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/utilities/getVariables.ts b/src/utilities/getVariables.ts index 3a1cd893..d89f6e34 100644 --- a/src/utilities/getVariables.ts +++ b/src/utilities/getVariables.ts @@ -8,6 +8,7 @@ import { changeNotation } from './changeNotation' import { getVariableTypeByValue } from './getVariableTypeByValue' import roundWithDecimals from './roundWithDecimals' import { Settings } from '@typings/settings' +import transformName from './transformName' const extractVariable = (variable, value, settings: Settings) => { let category: tokenCategoryType = 'color' @@ -20,7 +21,7 @@ const extractVariable = (variable, value, settings: Settings) => { description: variable.description || undefined, exportKey: tokenTypes.variables.key as tokenExportKeyType, category: getVariableTypeByValue(Object.values(resolvedAlias.valuesByMode)[0]), - values: `{${collection.name.toLowerCase()}.${changeNotation(resolvedAlias.name, '/', '.', settings.nameConversion)}}`, + values: `{${transformName(collection.name.toLowerCase(), settings.nameConversion)}.${changeNotation(resolvedAlias.name, '/', '.', settings.nameConversion)}}`, // this is being stored so we can properly update the design tokens later to account for all // modes when using aliases From d78436c5e71407b816096a844a375eb38465ac1f Mon Sep 17 00:00:00 2001 From: Matthew Ratzke Date: Fri, 19 Jan 2024 19:45:31 -0700 Subject: [PATCH 3/4] additional fixes to variable aliases --- src/utilities/getVariables.ts | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/utilities/getVariables.ts b/src/utilities/getVariables.ts index d89f6e34..8031ba71 100644 --- a/src/utilities/getVariables.ts +++ b/src/utilities/getVariables.ts @@ -16,16 +16,17 @@ const extractVariable = (variable, value, settings: Settings) => { if (value.type === 'VARIABLE_ALIAS') { const resolvedAlias = figma.variables.getVariableById(value.id) const collection = figma.variables.getVariableCollectionById(resolvedAlias.variableCollectionId) + const aliasVariable = `${collection.name.toLocaleLowerCase()}/${resolvedAlias.name}` return { name: variable.name, description: variable.description || undefined, exportKey: tokenTypes.variables.key as tokenExportKeyType, category: getVariableTypeByValue(Object.values(resolvedAlias.valuesByMode)[0]), - values: `{${transformName(collection.name.toLowerCase(), settings.nameConversion)}.${changeNotation(resolvedAlias.name, '/', '.', settings.nameConversion)}}`, + values: `{${changeNotation(aliasVariable, '/', '.', settings.nameConversion)}}`, // this is being stored so we can properly update the design tokens later to account for all // modes when using aliases - aliasCollectionName: collection.name.toLowerCase(), + aliasCollectionName: transformName(collection.name.toLowerCase(), settings.nameConversion), aliasModes: collection.modes } } @@ -62,7 +63,7 @@ const extractVariable = (variable, value, settings: Settings) => { } } -const processAliasModes = (variables) => { +const processAliasModes = (variables, settings: Settings) => { return variables.reduce((collector, variable) => { // nothing needs to be done to variables that have no alias modes, or only one mode if (!variable.aliasModes || variable.aliasModes.length < 2) { @@ -79,7 +80,8 @@ const processAliasModes = (variables) => { for (const aliasMode of aliasModes) { const modeBasedVariable = { ...variable } - modeBasedVariable.values = modeBasedVariable.values.replace(new RegExp(`({${aliasCollectionName}.)`, "i"), `{${aliasCollectionName}.${aliasMode.name}.`) + const aliasModeName = transformName(aliasMode.name, settings.nameConversion) + modeBasedVariable.values = modeBasedVariable.values.replace(new RegExp(`({${aliasCollectionName}.)`, "i"), `{${aliasCollectionName}.${aliasModeName}.`) collector.push(modeBasedVariable) } @@ -100,16 +102,17 @@ export const getVariables = (figma: PluginAPI, settings: Settings) => { // return each mode value as a separate variable return Object.entries(variable.valuesByMode).map(([id, value]) => { // Only add mode if there's more than one - let addMode = settings.modeReference && modes.length > 1 + const addMode = settings.modeReference && modes.length > 1 + const currentMode = addMode && modes.find(({ modeId }) => modeId === id) return { ...extractVariable(variable, value, settings), // name is contstructed from collection, mode and variable name - name: addMode ? `${collection}/${modes.find(({ modeId }) => modeId === id).name}/${variable.name}` : `${collection}/${variable.name}`, + name: currentMode ? `${collection}/${currentMode.name}/${variable.name}` : `${collection}/${variable.name}`, // add mnetadata to extensions extensions: { [config.key.extensionPluginData]: { - mode: settings.modeReference ? modes.find(({ modeId }) => modeId === id).name : undefined, + mode: settings.modeReference ? currentMode.name : undefined, collection: collection, scopes: variable.scopes, [config.key.extensionVariableStyleId]: variable.id, @@ -119,5 +122,5 @@ export const getVariables = (figma: PluginAPI, settings: Settings) => { } }) }) - return settings.modeReference ? processAliasModes(variables.flat()) : variables.flat(); + return settings.modeReference ? processAliasModes(variables.flat(), settings) : variables.flat(); } \ No newline at end of file From 6192e888ecedf9222bbc120e300955a56bfbc786 Mon Sep 17 00:00:00 2001 From: Matthew Ratzke Date: Fri, 19 Jan 2024 19:58:31 -0700 Subject: [PATCH 4/4] replace for-loop with map --- src/utilities/getVariables.ts | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/src/utilities/getVariables.ts b/src/utilities/getVariables.ts index 8031ba71..59406d49 100644 --- a/src/utilities/getVariables.ts +++ b/src/utilities/getVariables.ts @@ -64,29 +64,27 @@ const extractVariable = (variable, value, settings: Settings) => { } const processAliasModes = (variables, settings: Settings) => { - return variables.reduce((collector, variable) => { + return variables.reduce((collector, variableWithModes) => { // nothing needs to be done to variables that have no alias modes, or only one mode - if (!variable.aliasModes || variable.aliasModes.length < 2) { - collector.push(variable) + if (!variableWithModes.aliasModes || variableWithModes.aliasModes.length < 2) { + collector.push(variableWithModes) return collector } - const { aliasModes, aliasCollectionName } = variable + const { aliasModes, aliasCollectionName, ...variableWithoutModes } = variableWithModes - // this was only added for this function to process that data so before we return the variables, we can remove it - delete variable.aliasModes - delete variable.aliasCollectionName - - for (const aliasMode of aliasModes) { - const modeBasedVariable = { ...variable } - const aliasModeName = transformName(aliasMode.name, settings.nameConversion) - modeBasedVariable.values = modeBasedVariable.values.replace(new RegExp(`({${aliasCollectionName}.)`, "i"), `{${aliasCollectionName}.${aliasModeName}.`) - - collector.push(modeBasedVariable) - } - - return collector + return [ + ...collector, + ...aliasModes.map(aliasMode => { + const aliasModeName = transformName(aliasMode.name, settings.nameConversion) + + return { + ...variableWithoutModes, + values: variableWithoutModes.values.replace(new RegExp(`({${aliasCollectionName}.)`, "i"), `{${aliasCollectionName}.${aliasModeName}.`) + }; + }) + ] }, []) }