Skip to content

Commit

Permalink
Merge branch 'main' into fix/3150-gradient-style-nested-reference
Browse files Browse the repository at this point in the history
  • Loading branch information
macintoshhelper authored Oct 3, 2024
2 parents 36c3607 + a6eb07d commit 3190587
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 67 deletions.
5 changes: 5 additions & 0 deletions .changeset/weak-oranges-buy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tokens-studio/figma-plugin": patch
---

fixes a bug where applying a typography token to a text node would override individual property changes (like font size or font family) when "Apply to selection/page/document" is clicked.
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ describe('Can set values on node', () => {
expect(setTextValuesOnTargetSpy).not.toHaveBeenCalled();
});

it('calls setTextValuesOnTarget if text node and composite typography tokens are given', async () => {
it('does not call setTextValuesOnTarget if text node and composite typography tokens are given', async () => {
defaultTokenValueRetriever.initiate({
tokens: [
{
Expand Down Expand Up @@ -265,7 +265,7 @@ describe('Can set values on node', () => {
},
},
);
expect(setTextValuesOnTargetSpy).toHaveBeenCalled();
expect(setTextValuesOnTargetSpy).not.toHaveBeenCalled();
});

it('sets textstyle if matching Style is found', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,80 +8,75 @@ import { NodeTokenRefMap } from '@/types/NodeTokenRefMap';
import { MapValuesToTokensResult } from '@/types';
import { tryApplyTypographyCompositeVariable } from './tryApplyTypographyCompositeVariable';

function buildResolvedValueObject(data: any) {
return {
fontFamily: isPrimitiveValue(data.fontFamilies) ? String(data.fontFamilies.startsWith('{') ? data.fontFamilies : `{${data.fontFamilies}}`) : undefined,
fontWeight: isPrimitiveValue(data.fontWeights) ? String(data.fontWeights.startsWith('{') ? data.fontWeights : `{${data.fontWeights}}`) : undefined,
lineHeight: isPrimitiveValue(data.lineHeights) ? String(data.lineHeights.startsWith('{') ? data.lineHeights : `{${data.lineHeights}}`) : undefined,
fontSize: isPrimitiveValue(data.fontSizes) ? String(data.fontSizes.startsWith('{') ? data.fontSizes : `{${data.fontSizes}}`) : undefined,
letterSpacing: isPrimitiveValue(data.letterSpacing) ? String(data.letterSpacing.startsWith('{') ? data.letterSpacing : `{${data.letterSpacing}}`) : undefined,
paragraphSpacing: isPrimitiveValue(data.paragraphSpacing) ? String(data.paragraphSpacing.startsWith('{') ? data.paragraphSpacing : `{${data.paragraphSpacing}}`) : undefined,
textCase: isPrimitiveValue(data.textCase) ? String(data.textCase.startsWith('{') ? data.textCase : `{${data.textCase}}`) : undefined,
textDecoration: isPrimitiveValue(data.textDecoration) ? String(data.textDecoration.startsWith('{') ? data.textDecoration : `{${data.textDecoration}}`) : undefined,
};
}

function buildValueObject(values: any, resolvedToken: any) {
const tokenValue = resolvedToken?.value || {};

return {
fontFamily: isPrimitiveValue(values.fontFamilies) ? String(values.fontFamilies) : tokenValue.fontFamily,
fontWeight: isPrimitiveValue(values.fontWeights) ? String(values.fontWeights) : tokenValue.fontWeight,
lineHeight: isPrimitiveValue(values.lineHeights) ? String(values.lineHeights) : tokenValue.lineHeight,
fontSize: isPrimitiveValue(values.fontSizes) ? String(values.fontSizes) : tokenValue.fontSize,
letterSpacing: isPrimitiveValue(values.letterSpacing) ? String(values.letterSpacing) : tokenValue.letterSpacing,
paragraphSpacing: isPrimitiveValue(values.paragraphSpacing) ? String(values.paragraphSpacing) : tokenValue.paragraphSpacing,
textCase: isPrimitiveValue(values.textCase) ? String(values.textCase) : tokenValue.textCase,
textDecoration: isPrimitiveValue(values.textDecoration) ? String(values.textDecoration) : tokenValue.textDecoration,
};
}

export async function applyTypographyTokenOnNode(
node: BaseNode,
data: NodeTokenRefMap,
values: MapValuesToTokensResult,
baseFontSize: string,
) {
if (!(node.type === 'TEXT')) return;
if (values.typography && data.typography) {
const resolvedToken = defaultTokenValueRetriever.get(data.typography);
let matchingStyleId = resolvedToken.styleId;

// Note: We should remove "backup style id" logic from here (this part). This was relevant before we had Themes, where style ids could not be saved to a token yet.
if (!matchingStyleId && isSingleTypographyValue(resolvedToken.value)) {
const styleIdBackupKey = 'textStyleId_original';
const nonLocalStyle = getNonLocalStyle(node, styleIdBackupKey, 'typography');
if (nonLocalStyle) {
if (textStyleMatchesTypographyToken(nonLocalStyle, resolvedToken.value, baseFontSize)) {
// Non-local style matches - use this and clear style id backup:
matchingStyleId = nonLocalStyle.id;
clearStyleIdBackup(node, styleIdBackupKey);
} else if (resolvedToken.adjustedTokenName === nonLocalStyle.name) {
// Non-local style does NOT match, but style name and token path does,
// so we assume selected token value is an override (e.g. dark theme)
// Now backup up style id before overwriting with raw token value, so we
// can re-link the non-local style, when the token value matches again:
setStyleIdBackup(node, styleIdBackupKey, nonLocalStyle.id);
}
}
}
const resolvedToken = data.typography ? defaultTokenValueRetriever.get(data.typography) : null;
let matchingStyleId = resolvedToken?.styleId;

if (
node.type === 'TEXT'
&& (!matchingStyleId || (matchingStyleId && !(await trySetStyleId(node, 'text', matchingStyleId))))
) {
if (isSingleTypographyValue(resolvedToken.value)) {
setTextValuesOnTarget(node, data.typography, baseFontSize);
}
// Backup logic for non-local styles
if (!matchingStyleId && resolvedToken && isSingleTypographyValue(resolvedToken.value)) {
const styleIdBackupKey = 'textStyleId_original';
const nonLocalStyle = getNonLocalStyle(node, styleIdBackupKey, 'typography');
if (nonLocalStyle && textStyleMatchesTypographyToken(nonLocalStyle, resolvedToken.value, baseFontSize)) {
matchingStyleId = nonLocalStyle.id;
clearStyleIdBackup(node, styleIdBackupKey);
} else if (nonLocalStyle && resolvedToken.adjustedTokenName === nonLocalStyle?.name) {
setStyleIdBackup(node, styleIdBackupKey, nonLocalStyle.id);
}
}
if (
values.fontFamilies
|| values.fontWeights
|| values.lineHeights
|| values.fontSizes
|| values.letterSpacing
|| values.paragraphSpacing
|| values.textCase
|| values.textDecoration
) {
const resolvedValueObject = {
fontFamily: isPrimitiveValue(data.fontFamilies) ? String(data.fontFamilies.startsWith('{') ? data.fontFamilies : `{${data.fontFamilies}}`) : undefined,
fontWeight: isPrimitiveValue(data.fontWeights) ? String(data.fontWeights.startsWith('{') ? data.fontWeights : `{${data.fontWeights}}`) : undefined,
lineHeight: isPrimitiveValue(data.lineHeights) ? String(data.lineHeights.startsWith('{') ? data.lineHeights : `{${data.lineHeights}}`) : undefined,
fontSize: isPrimitiveValue(data.fontSizes) ? String(data.fontSizes.startsWith('{') ? data.fontSizes : `{${data.fontSizes}}`) : undefined,
letterSpacing: isPrimitiveValue(data.letterSpacing) ? String(data.letterSpacing.startsWith('{') ? data.letterSpacing : `{${data.letterSpacing}}`) : undefined,
paragraphSpacing: isPrimitiveValue(data.paragraphSpacing) ? String(data.paragraphSpacing.startsWith('{') ? data.paragraphSpacing : `{${data.paragraphSpacing}}`) : undefined,
textCase: isPrimitiveValue(data.textCase) ? String(data.textCase.startsWith('{') ? data.textCase : `{${data.textCase}}`) : undefined,
textDecoration: isPrimitiveValue(data.textDecoration) ? String(data.textDecoration.startsWith('{') ? data.textDecoration : `{${data.textDecoration}}`) : undefined,
}
const valueObject = {
fontFamily: isPrimitiveValue(values.fontFamilies) ? String(values.fontFamilies) : undefined,
fontWeight: isPrimitiveValue(values.fontWeights) ? String(values.fontWeights) : undefined,
lineHeight: isPrimitiveValue(values.lineHeights) ? String(values.lineHeights) : undefined,
fontSize: isPrimitiveValue(values.fontSizes) ? String(values.fontSizes) : undefined,
letterSpacing: isPrimitiveValue(values.letterSpacing) ? String(values.letterSpacing) : undefined,
paragraphSpacing: isPrimitiveValue(values.paragraphSpacing) ? String(values.paragraphSpacing) : undefined,
textCase: isPrimitiveValue(values.textCase) ? String(values.textCase) : undefined,
textDecoration: isPrimitiveValue(values.textDecoration) ? String(values.textDecoration) : undefined,
};
await tryApplyTypographyCompositeVariable({
target: node,
value: valueObject,
resolvedValue: resolvedValueObject,
baseFontSize,
});

// Apply matching style or fallback to applying values
if (matchingStyleId && (await trySetStyleId(node, 'text', matchingStyleId))) return;

// Apply typography token directly if no other properties exist
if (data.typography && resolvedToken && isSingleTypographyValue(resolvedToken.value) && !Object.keys(values).length) {
setTextValuesOnTarget(node, data.typography, baseFontSize);
return;
}
}

// Build the resolved value and value objects
const resolvedValueObject = buildResolvedValueObject(data);
const valueObject = buildValueObject(values, resolvedToken);

// Apply the typography token and other values together
await tryApplyTypographyCompositeVariable({
target: node,
value: valueObject,
resolvedValue: resolvedValueObject,
baseFontSize,
});
}

0 comments on commit 3190587

Please sign in to comment.