Skip to content

Commit

Permalink
Merge 6fabc2e into e7ae576
Browse files Browse the repository at this point in the history
  • Loading branch information
marcomontalbano committed May 23, 2023
2 parents e7ae576 + 6fabc2e commit 5452cf2
Show file tree
Hide file tree
Showing 32 changed files with 975 additions and 72 deletions.
4 changes: 4 additions & 0 deletions .figmaexportrc.example.local.ts
Expand Up @@ -11,6 +11,7 @@ import { FigmaExportRC, StylesCommandOptions, ComponentsCommandOptions } from '.
import outputStylesAsCss from './packages/output-styles-as-css';
import outputStylesAsLess from './packages/output-styles-as-less';
import outputStylesAsSass from './packages/output-styles-as-sass';
import outputStylesAsStyleDictionary from './packages/output-styles-as-style-dictionary';
import transformSvgWithSvgo from './packages/transform-svg-with-svgo';
import outputComponentsAsEs6 from './packages/output-components-as-es6';
import outputComponentsAsSvg from './packages/output-components-as-svg';
Expand All @@ -29,6 +30,9 @@ const styleOptions: StylesCommandOptions = {
}),
outputStylesAsSass({
output: './output/styles/sass'
}),
outputStylesAsStyleDictionary({
output: './output/styles/style-dictionary'
})
]
};
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/publish.yml
Expand Up @@ -10,12 +10,12 @@ jobs:

steps:
- name: Checkout 🛎️
uses: actions/checkout@v1
uses: actions/checkout@v3

- name: Node 🧰
uses: actions/setup-node@v1
uses: actions/setup-node@v3
with:
node-version: 14.x
node-version: 18.x

- name: Install 📦
run: |
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/release.yml
Expand Up @@ -10,7 +10,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout 🛎️
uses: actions/checkout@v1.0.0
uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Get tag info 🏷
id: tags
Expand Down
18 changes: 9 additions & 9 deletions .github/workflows/test.yml
Expand Up @@ -14,14 +14,14 @@ jobs:

strategy:
matrix:
node: [12.22.0, 12.x, 14.x, 16.x, 18.x]
node: [12.22.0, 12.x, 14.x, 16.x, 18.x, 20.x]

steps:
- name: Checkout 🛎️
uses: actions/checkout@v2
uses: actions/checkout@v3

- name: Node 🧰
uses: actions/setup-node@v2
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}

Expand All @@ -41,10 +41,10 @@ jobs:

steps:
- name: Checkout 🛎️
uses: actions/checkout@v2
uses: actions/checkout@v3

- name: Node 🧰
uses: actions/setup-node@v2
uses: actions/setup-node@v3
with:
node-version: 16.x

Expand All @@ -61,7 +61,7 @@ jobs:
path-to-lcov: ./coverage/lcov.info # optional (default value)

- name: Upload `coverage` artifact
uses: actions/upload-artifact@v1
uses: actions/upload-artifact@v3
with:
name: coverage
path: coverage/lcov-report
Expand All @@ -73,10 +73,10 @@ jobs:

# steps:
# - name: Checkout 🛎️
# uses: actions/checkout@v2
# uses: actions/checkout@v3

# - name: Node 🧰
# uses: actions/setup-node@v2
# uses: actions/setup-node@v3
# with:
# node-version: 14.x

Expand All @@ -87,7 +87,7 @@ jobs:
# run: yarn stryker

# - name: Upload `stryker` artifact
# uses: actions/upload-artifact@v1
# uses: actions/upload-artifact@v3
# with:
# name: stryker
# path: reports/mutation/html
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -27,7 +27,7 @@ You can export your Figma Components as SVG and use them inside your website.
### Styles

You can export your Figma Styles into different output like `.sass` format, `.scss` format or you can create your own outputter.
You can export your Figma Styles into different output like `.sass` format, `.scss` format, [`Style Dictionary`](https://amzn.github.io/style-dictionary/#/) tokens or you can create your own outputter.

> If you want to keep the style of your Figma file in-sync with the `.css` of your website, this is a must-have.
Expand Down
1 change: 1 addition & 0 deletions packages/cli/README.md
Expand Up @@ -157,5 +157,6 @@ or install an official outputter:
| Package | Version |
|---------|---------|
| [`@figma-export/output-styles-as-css`](/packages/output-styles-as-css) | [![npm](https://img.shields.io/npm/v/@figma-export/output-styles-as-css.svg?maxAge=3600)](https://www.npmjs.com/package/@figma-export/output-styles-as-css) |
| [`@figma-export/output-styles-as-style-dictionary`](/packages/output-styles-as-style-dictionary) | [![npm](https://img.shields.io/npm/v/@figma-export/output-styles-as-style-dictionary.svg?maxAge=3600)](https://www.npmjs.com/package/@figma-export/output-styles-as-style-dictionary) |
| [`@figma-export/output-styles-as-sass`](/packages/output-styles-as-sass) | [![npm](https://img.shields.io/npm/v/@figma-export/output-styles-as-sass.svg?maxAge=3600)](https://www.npmjs.com/package/@figma-export/output-styles-as-sass) |
| [`@figma-export/output-styles-as-less`](/packages/output-styles-as-less) | [![npm](https://img.shields.io/npm/v/@figma-export/output-styles-as-less.svg?maxAge=3600)](https://www.npmjs.com/package/@figma-export/output-styles-as-less) |
4 changes: 2 additions & 2 deletions packages/output-components-as-es6/src/index.test.ts
Expand Up @@ -11,8 +11,8 @@ import * as FigmaExport from '@figma-export/types';
import * as figmaDocument from '../../core/src/lib/_config.test';
import * as figma from '../../core/src/lib/figma';

import fs = require('fs');
import outputter = require('./index');
import fs from 'fs';
import outputter from './index';

describe('outputter as es6', () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down
4 changes: 2 additions & 2 deletions packages/output-components-as-svg/src/index.test.ts
Expand Up @@ -2,9 +2,9 @@ import sinon from 'sinon';
import { expect } from 'chai';
import * as figmaDocument from '../../core/src/lib/_config.test';
import * as figma from '../../core/src/lib/figma';
import fs = require('fs');

import outputter = require('./index');
import fs from 'fs';
import outputter from './index';

describe('outputter as svg', () => {
beforeEach(() => {
Expand Down
4 changes: 2 additions & 2 deletions packages/output-components-as-svgr/src/index.test.ts
Expand Up @@ -5,9 +5,9 @@ import nock from 'nock';
import { camelCase, kebabCase } from '@figma-export/utils';
import * as figmaDocument from '../../core/src/lib/_config.test';
import * as figma from '../../core/src/lib/figma';
import fs = require('fs');

import outputter = require('./index');
import fs from 'fs';
import outputter from './index';

describe('outputter as svgr', () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down
5 changes: 2 additions & 3 deletions packages/output-components-as-svgstore/src/index.test.ts
Expand Up @@ -4,9 +4,8 @@ import { expect } from 'chai';
import * as figmaDocument from '../../core/src/lib/_config.test';
import * as figma from '../../core/src/lib/figma';

// eslint-disable-next-line import/order
import fs = require('fs');
import outputter = require('./index');
import fs from 'fs';
import outputter from './index';

describe('outputter as svgstore', () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down
2 changes: 1 addition & 1 deletion packages/output-styles-as-css/README.md
Expand Up @@ -44,7 +44,7 @@ const { kebabCase } = require('@figma-export/utils');
require('@figma-export/output-styles-as-css')({
output: './output',
getFilename: () => '_variables',
getVariableName: (style) => kebabCase(style.name).toLowerCase(),
getVariableName = (style, descriptor) => `${kebabCase(style.name).toLowerCase()}${descriptor != null ? `-${descriptor}` : ''}`,
})
```

Expand Down
5 changes: 2 additions & 3 deletions packages/output-styles-as-css/src/index.test.ts
Expand Up @@ -8,9 +8,8 @@ import {
} from '@figma-export/types';
import { camelCase } from '@figma-export/utils';

// eslint-disable-next-line import/order
import fs = require('fs');
import outputter = require('./index');
import fs from 'fs';
import outputter from './index';

const mockFill = (fills: FillStyle[], { visible = true, name = 'variable/name', comment = 'lorem ipsum' } = {}): Style => ({
fills,
Expand Down
34 changes: 16 additions & 18 deletions packages/output-styles-as-css/src/index.ts
@@ -1,29 +1,27 @@
import * as FigmaExport from '@figma-export/types';
import { kebabCase } from '@figma-export/utils';

import { writeVariable, writeComment, sanitizeText } from './utils';
import { sanitizeText, writeComment, writeVariable } from './utils';

import fs = require('fs');
import path = require('path');

type Options = {
output: string;
getFilename?: () => string;
getVariableName?: (style: FigmaExport.Style) => string;
getVariableName?: FigmaExport.GetVariableName;
}

export = ({
output,
getFilename = () => '_variables',
getVariableName = (style) => kebabCase(style.name).toLowerCase(),
getVariableName = (style, descriptor) => `${kebabCase(style.name).toLowerCase()}${descriptor != null ? `-${descriptor}` : ''}`,
}: Options): FigmaExport.StyleOutputter => {
return async (styles) => {
let text = '';

styles.forEach((style) => {
if (style.visible) {
const variableName = getVariableName(style);

// eslint-disable-next-line default-case
switch (style.styleType) {
case 'FILL': {
Expand All @@ -34,7 +32,7 @@ export = ({

if (value) {
text += writeComment(style.comment);
text += writeVariable(variableName, value);
text += writeVariable(getVariableName(style), value);
}

break;
Expand All @@ -58,25 +56,25 @@ export = ({

if (value) {
text += writeComment(style.comment);
text += writeVariable(variableName, value);
text += writeVariable(getVariableName(style), value);
}

break;
}

case 'TEXT': {
text += writeComment(style.comment);
text += writeVariable(`${variableName}-font-family`, `"${style.style.fontFamily}"`);
text += writeVariable(`${variableName}-font-size`, `${style.style.fontSize}px`);
text += writeVariable(`${variableName}-font-style`, `${style.style.fontStyle}`);
text += writeVariable(`${variableName}-font-variant`, `${style.style.fontVariant}`);
text += writeVariable(`${variableName}-font-weight`, `${style.style.fontWeight}`);
text += writeVariable(`${variableName}-letter-spacing`, `${style.style.letterSpacing}px`);
text += writeVariable(`${variableName}-line-height`, `${style.style.lineHeight}px`);
text += writeVariable(`${variableName}-text-align`, `${style.style.textAlign}`);
text += writeVariable(`${variableName}-text-decoration`, `${style.style.textDecoration}`);
text += writeVariable(`${variableName}-text-transform`, `${style.style.textTransform}`);
text += writeVariable(`${variableName}-vertical-align`, `${style.style.verticalAlign}`);
text += writeVariable(getVariableName(style, 'font-family'), `"${style.style.fontFamily}"`);
text += writeVariable(getVariableName(style, 'font-size'), `${style.style.fontSize}px`);
text += writeVariable(getVariableName(style, 'font-style'), `${style.style.fontStyle}`);
text += writeVariable(getVariableName(style, 'font-variant'), `${style.style.fontVariant}`);
text += writeVariable(getVariableName(style, 'font-weight'), `${style.style.fontWeight}`);
text += writeVariable(getVariableName(style, 'letter-spacing'), `${style.style.letterSpacing}px`);
text += writeVariable(getVariableName(style, 'line-height'), `${style.style.lineHeight}px`);
text += writeVariable(getVariableName(style, 'text-align'), `${style.style.textAlign}`);
text += writeVariable(getVariableName(style, 'text-decoration'), `${style.style.textDecoration}`);
text += writeVariable(getVariableName(style, 'text-transform'), `${style.style.textTransform}`);
text += writeVariable(getVariableName(style, 'vertical-align'), `${style.style.verticalAlign}`);

break;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/output-styles-as-less/README.md
Expand Up @@ -44,7 +44,7 @@ const { kebabCase } = require('@figma-export/utils');
require('@figma-export/output-styles-as-less')({
output: './output',
getFilename: () => '_variables',
getVariableName: (style) => kebabCase(style.name).toLowerCase(),
getVariableName = (style, descriptor) => `${kebabCase(style.name).toLowerCase()}${descriptor != null ? `-${descriptor}` : ''}`,
})
```

Expand Down
29 changes: 25 additions & 4 deletions packages/output-styles-as-less/src/index.test.ts
Expand Up @@ -8,9 +8,8 @@ import {
} from '@figma-export/types';
import { camelCase } from '@figma-export/utils';

// eslint-disable-next-line import/order
import fs = require('fs');
import outputter = require('./index');
import fs from 'fs';
import outputter from './index';

const mockFill = (fills: FillStyle[], { visible = true, name = 'variable/name', comment = 'lorem ipsum' } = {}): Style => ({
fills,
Expand Down Expand Up @@ -317,7 +316,29 @@ describe('style output as less', () => {
+ 'text-decoration: none;\n'
+ 'text-transform: uppercase;\n'
+ 'vertical-align: middle;\n'
+ '};\n',
+ '};\n'
+ '\n\n'
+ '@variable-name-font-family: "Verdana";\n'
+ '\n\n'
+ '@variable-name-font-size: 12px;\n'
+ '\n\n'
+ '@variable-name-font-style: italic;\n'
+ '\n\n'
+ '@variable-name-font-variant: normal;\n'
+ '\n\n'
+ '@variable-name-font-weight: 100;\n'
+ '\n\n'
+ '@variable-name-letter-spacing: 10px;\n'
+ '\n\n'
+ '@variable-name-line-height: 12px;\n'
+ '\n\n'
+ '@variable-name-text-align: left;\n'
+ '\n\n'
+ '@variable-name-text-decoration: none;\n'
+ '\n\n'
+ '@variable-name-text-transform: uppercase;\n'
+ '\n\n'
+ '@variable-name-vertical-align: middle;\n',
);
});
});
Expand Down
26 changes: 18 additions & 8 deletions packages/output-styles-as-less/src/index.ts
@@ -1,29 +1,27 @@
import * as FigmaExport from '@figma-export/types';
import { kebabCase } from '@figma-export/utils';

import { writeVariable, writeMap } from './utils';
import { writeMap, writeVariable } from './utils';

import fs = require('fs');
import path = require('path');

type Options = {
output: string;
getFilename?: () => string;
getVariableName?: (style: FigmaExport.Style) => string;
getVariableName?: FigmaExport.GetVariableName;
}

export = ({
output,
getFilename = () => '_variables',
getVariableName = (style) => kebabCase(style.name).toLowerCase(),
getVariableName = (style, descriptor) => `${kebabCase(style.name).toLowerCase()}${descriptor != null ? `-${descriptor}` : ''}`,
}: Options): FigmaExport.StyleOutputter => {
return async (styles) => {
let text = '';

styles.forEach((style) => {
if (style.visible) {
const variableName = getVariableName(style);

// eslint-disable-next-line default-case
switch (style.styleType) {
case 'FILL': {
Expand All @@ -32,7 +30,7 @@ export = ({
.map((fill) => fill.value)
.join(', ');

text += writeVariable(style.comment, variableName, value);
text += writeVariable(style.comment, getVariableName(style), value);

break;
}
Expand All @@ -51,7 +49,7 @@ export = ({
.join(', ');

// Shadow and Blur effects cannot be combined together since they use two different CSS properties.
text += writeVariable(style.comment, variableName, boxShadowValue || filterBlurValue);
text += writeVariable(style.comment, getVariableName(style), boxShadowValue || filterBlurValue);

break;
}
Expand All @@ -71,7 +69,19 @@ export = ({
vertical-align: ${style.style.verticalAlign};
}`;

text += writeMap(style.comment, variableName, value);
text += writeMap(style.comment, getVariableName(style), value);

text += writeVariable(style.comment, getVariableName(style, 'font-family'), `"${style.style.fontFamily}"`);
text += writeVariable(style.comment, getVariableName(style, 'font-size'), `${style.style.fontSize}px`);
text += writeVariable(style.comment, getVariableName(style, 'font-style'), `${style.style.fontStyle}`);
text += writeVariable(style.comment, getVariableName(style, 'font-variant'), `${style.style.fontVariant}`);
text += writeVariable(style.comment, getVariableName(style, 'font-weight'), `${style.style.fontWeight}`);
text += writeVariable(style.comment, getVariableName(style, 'letter-spacing'), `${style.style.letterSpacing}px`);
text += writeVariable(style.comment, getVariableName(style, 'line-height'), `${style.style.lineHeight}px`);
text += writeVariable(style.comment, getVariableName(style, 'text-align'), `${style.style.textAlign}`);
text += writeVariable(style.comment, getVariableName(style, 'text-decoration'), `${style.style.textDecoration}`);
text += writeVariable(style.comment, getVariableName(style, 'text-transform'), `${style.style.textTransform}`);
text += writeVariable(style.comment, getVariableName(style, 'vertical-align'), `${style.style.verticalAlign}`);

break;
}
Expand Down

0 comments on commit 5452cf2

Please sign in to comment.