Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…into 2339-gitlab-issue-connecting-to-repo
  • Loading branch information
robinhoodie0823 committed Nov 2, 2023
2 parents b323bcf + 23ff708 commit 2d0b657
Show file tree
Hide file tree
Showing 12 changed files with 104 additions and 33 deletions.
5 changes: 0 additions & 5 deletions .changeset/dirty-otters-notice.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/lazy-experts-switch.md

This file was deleted.

5 changes: 5 additions & 0 deletions .changeset/little-items-double.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tokens-studio/figma-plugin': patch
---

Fixes an issue that causes a crash when interacting with a numeric token, such as duplicating
5 changes: 0 additions & 5 deletions .changeset/neat-tools-hammer.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/selfish-buttons-guess.md

This file was deleted.

5 changes: 0 additions & 5 deletions .changeset/slow-houses-draw.md

This file was deleted.

11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# @tokens-studio/figma-plugin

## 1.38.2

### Patch Changes

- 1e5beacb: We now carry over token descriptions when creating variables
- abf1cb0b: Fixed an issue that caused the active theme to be reset when you were editing it in Manage themes
- 20189a39: Changing a token group's name now lets you also rename attached styles and variables
- e5de5250: Reintroduces support for nested references for 1 level deep (use at your own risk, this affects performance). For example, you can use `{colors.{primary}.500}` but not `{colors.{brand.{primary}}}`.
- 02ac59b5: We now show token values in the inspect tab using tooltips to preview the value
- 572840bd: Fixed a bug where expired license keys could not be removed

## 1.38.1

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tokens-studio/figma-plugin",
"version": "1.38.1",
"version": "1.38.2",
"description": "Tokens Studio plugin for Figma",
"license": "MIT",
"private": true,
Expand Down
5 changes: 3 additions & 2 deletions src/app/components/DownshiftInput/MentionInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,14 @@ export default function MentionsInput({
}, [handleBlur]);

const getHighlightedText = React.useCallback((text: string, highlight: string) => {
// Note that the highlight might be numeric, hence we cast it to a string
// Split on highlight term and include term into parts, ignore case
const parts = text.split(new RegExp(`(${highlight.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')})`, 'gi'));
const parts = text.split(new RegExp(`(${String(highlight).replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')})`, 'gi'));
return (
<span>
{parts.map((part, i) => (
// eslint-disable-next-line react/no-array-index-key
<StyledPart key={i} matches={part.toLowerCase() === highlight.toLowerCase()}>
<StyledPart key={i} matches={part.toLowerCase() === String(highlight).toLowerCase()}>
{part}
</StyledPart>
))}
Expand Down
2 changes: 1 addition & 1 deletion src/constants/AliasRegex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
export const checkAliasStartRegex = /(\$[^\s,]+\w)|({([^]*))/g;

// evaluates tokens such as $foo or {foo}
export const AliasRegex = /(?:\$([^\s,]+\w))|(?:{([^}]*)})/g;
export const AliasRegex = /\{((?:[^{}]|{[^{}]*})*)\}|(?:\$([^\s,]+\w))/g;

export const AliasDollarRegex = /(?:\$([^\s,]+\w))/g;
55 changes: 55 additions & 0 deletions src/utils/TokenResolver.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,31 @@ const tokens = [
value: '{typography.all.fontFamily}',
type: TokenTypes.FONT_FAMILIES,
},
{
name: 'colors.lilac.500',
value: '#ff0000',
type: TokenTypes.COLOR,
},
{
name: 'primary',
value: 'lilac',
type: TokenTypes.OTHER,
},
{
name: 'nestedprimary',
value: '{primary}',
type: TokenTypes.OTHER,
},
{
name: 'thatprimarycolor',
value: '{colors.{primary}.500}',
type: TokenTypes.COLOR,
},
{
name: 'thatnestedprimarycolor',
value: '{colors.{nestedprimary}.500}',
type: TokenTypes.COLOR,
},
];

const output = [
Expand Down Expand Up @@ -468,6 +493,36 @@ const output = [
rawValue: '{typography.all.fontFamily}',
type: TokenTypes.FONT_FAMILIES,
},
{
name: 'colors.lilac.500',
value: '#ff0000',
rawValue: '#ff0000',
type: TokenTypes.COLOR,
},
{
name: 'primary',
value: 'lilac',
rawValue: 'lilac',
type: TokenTypes.OTHER,
},
{
name: 'nestedprimary',
value: 'lilac',
rawValue: '{primary}',
type: TokenTypes.OTHER,
},
{
name: 'thatprimarycolor',
value: '#ff0000',
rawValue: '{colors.{primary}.500}',
type: TokenTypes.COLOR,
},
{
name: 'thatnestedprimarycolor',
value: '#ff0000',
rawValue: '{colors.{nestedprimary}.500}',
type: TokenTypes.COLOR,
},
];
describe('resolveTokenValues deep nested', () => {
it('resolves all values it can resolve', () => {
Expand Down
32 changes: 28 additions & 4 deletions src/utils/TokenResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,21 +124,45 @@ class TokenResolver {
} as ResolveTokenValuesResult;
}

// Users can nest references, so we need to make sure to resolve any nested references first.
let resolvedPath = path;
let matches: boolean = true;

// As long as we have matches, we need to resolve them. This is needed for multiple levels of nesting. Performance will suffer, but that's the user's choice.
while (matches !== false) {
const match = resolvedPath.match(AliasRegex);
matches = Boolean(match?.length);
if (!match?.length) break;

const nestedTokenName = getPathName(match[0]);
const nestedToken = this.tokenMap.get(nestedTokenName);

if (nestedToken && nestedToken.value) {
const resolvedNestedToken = this.resolveReferences({ ...nestedToken, name: nestedTokenName } as SingleToken, new Set(resolvedReferences));

if (typeof resolvedNestedToken.value === 'string' || typeof resolvedNestedToken.value === 'number') {
resolvedPath = resolvedPath.replace(match[0], resolvedNestedToken.value);
}
} else {
break;
}
}

// We have the special case of deep references where we can reference the .fontFamily property of a typography token.
// For that case, we need to split the path and get the last part, which might be the property name.
// However, it might not be. If we have a token called "color.primary" and we reference "color.primary.fontFamily", we need to check if "color.primary" exists. If it does, we prefer to return that one.
// If it doesn't it might be a composite token where we want to return the atomic property
const propertyPath = path.split('.');
const propertyPath = resolvedPath.split('.');
const propertyName = propertyPath.pop() as string;
const tokenNameWithoutLastPart = propertyPath.join('.');
const foundToken = this.tokenMap.get(path);
const foundToken = this.tokenMap.get(resolvedPath);

if (foundToken) {
// We add the already resolved references to the new set, so we can check for circular references
const newResolvedReferences = new Set(resolvedReferences);
newResolvedReferences.add(path);
newResolvedReferences.add(resolvedPath);
// We initiate a new resolveReferences call, as we need to resolve the references of the reference
const resolvedTokenValue = this.resolveReferences({ ...foundToken, name: path } as SingleToken, newResolvedReferences);
const resolvedTokenValue = this.resolveReferences({ ...foundToken, name: resolvedPath } as SingleToken, newResolvedReferences);

// We weren't able to resolve the reference, so we return the token as is, but mark it as failed to resolve
if (resolvedTokenValue.value === undefined) {
Expand Down

0 comments on commit 2d0b657

Please sign in to comment.