Frontend/Article

Style Dictionary 사용 방법 정리(feat. 피그마 디자인 토큰 가공하기)

BeNI 2023. 9. 23. 17:53
728x90

 

 

 

이번 글에서는 Style Dictionary가 무엇인지와 사용 방법을 간단히 정리하고자 한다 

 

 

 

1. 디자인 시스템과 Style Dictionary

 

Style Dictionary가 무엇인지 알기 전에, 디자인 시스템이 무엇인지 알 필요성이 있다.

 

gpt 최고!

 

쉽게 설명하자면, 디자인 시스템은 디자인과 개발을 좀 더 쉽게, 일관되게, 효율적으로 만들고 관리하는 방법이라고 할 수 있다.

 

그러면 Style Dictionary와 디자인 시스템이 무슨 상관이 있는 걸까?

 

 

Style Dictionary는 디자인 시스템에서 사용되는 디자인 토큰을 관리하고 적용하는 오픈 소스이다.

* 디자인 토큰: 디자인에서 사용되는 요소(글꼴, 색상, 그림자 등)을 표준화 한 요소

 

그럼 디자인 토큰이 왜 필요한 걸까?

 

디자인 토큰은 css변수를 설정하는 것과 같은 이치라고 볼 수 있다. 

예를 들어, 본문의 color를 #f5f5f5라고 정해놨다고 하자.

만약 우리가 본문이 있는 곳마다 color: #f5f5f5라고 작성을 해놓았는데 

맙소사, 갑자기 본문의 color가 #f6f6f6으로 바뀌어버리면 우리는 #f5f5f5가 있는 곳마다 일일이 다 바꿔줘야 할 것이다.

 

하지만 우리가 mainColor: #f5f5f5 라고 정해놓고 color를 mainColor라고 지정해놨으면

mainColor 색상만 바꾸면 쉽게 전체 색상을 바꿀 수 있을 것이다.

 

 

 

2. 피그마의 디자인 토큰 추출

 

https://www.figma.com/community/file/876022745968684318

 

Bootstrap UI Kit | Figma Community

Bootstrap UI kit Bootstrap 5 starter UI Kit collection of bootstrap base components. Super excited to share my first file to the community. Its initial start of bootstrap components. -> More Details Change log Enjoy and feel free to share your comments and

www.figma.com

 

부트스트랩의 figma를 보며 디자인 토큰을 추출하고, style Dictionary로 가공해보자

 

피그마에서 디자인 토큰을 추출할 수 있는 곳은 stylesvariables 두 종류가 있다.

보통은 Local styles 많이 이용한다. (위 Bootstrap도 styles를 이용하고 있다)

 

 

피그마를 열어서 우측 패널을 보면 Local styles라고 Text style, color 등을 정의해 둔 부분이 있다.

우리는 저 요소를 json으로 추출하여 style dictionary로 가공 할 것이다.

 

 

styles를 json형태로 추출하는 방법은 플러그인을 이용하는 방법이 제일 간단하다 !

좌측 상단 패널에서 저 아이콘을 클릭하면 플러그인을 검색하고, 사용할 수 있다.

 

 

token이라고 검색하면 여러 플러그인들이 많이 나오는데, 우리는 저 노란색 아이콘을 가진 Design Tokens를 이용할 것이다.

 

 

클릭해서 export design token files를 누르면 아래 창이 뜬다

 

여기서 Figma Variables(BETA)를 제외하고는 styles에 정의한 부분들이다.

 

추출해서 json 파일을 보면 아래와 같다.

{
  "color": {
    "primary": {
      "color": {
        "description": "",
        "type": "color",
        "value": "#7749f8ff",
        "blendMode": "normal",
        "extensions": {
          "org.lukasoppermann.figmaDesignTokens": {
            "styleId": "S:a4a48d4ec66ef0f05bfa6d36fcb36361ca79ab4c,",
            "exportKey": "color"
          }
        }
      },
      "color dark": {
        "description": "",
        "type": "color",
        "value": "#5227ccff",
        "blendMode": "normal",
        "extensions": {
          "org.lukasoppermann.figmaDesignTokens": {
            "styleId": "S:0a2a37c25b70236776ff632aa7ff581a98b60a02,",
            "exportKey": "color"
          }
        }
      },
      ...
   }
}

color를 살펴보면 ...

primary라고 정의한 color가 value에 #7749f8ff 형태로 들어가 있는 것을 볼 수 있다.

 

 

 

 

3. Style Dictionary로 디자인 토큰을 CSS 변수 형태로 변환

 

사실 피그마 플러그인을 잘 찾아보면, styles -> css variables 로 바꿔주는 플러그인이 많이 있다.

하지만 해당 플러그인의 단점은 변수 이름이나 나오는 포맷을 커스텀하기 힘들다는 점이다.

 

style dictionary를 사용하면, 우리가 원하는 형태로 filter하고, format을 정하여 원하는 형태로 변환할 수 있다.

 

 

자! 새 프로젝트를 만들어서 style dictionary를 설치해 주자

 

$ npm install -D style-dictionary

 

설치한 후, 우리가 직접 config 파일을 만들어서 가공할 형태를 정의해줘야 한다 

transformToken.js를 만들어서(파일 이름 자유) 아래 코드를 복붙 해주자 !

 

const StyleDictionary = require('style-dictionary').extend({
  source: ['tokens/**/*.json'],
  platforms: {
    scss: {
      transformGroup: 'scss',
      buildPath: 'build/',
      files: [{
        destination: 'variables.scss',
        format: 'scss/variables'
      }]
    }
    // ...
  }
});

StyleDictionary.buildAllPlatforms();

위 코드가 node에서 가장 기본적인 형태다. (https://amzn.github.io/style-dictionary/#/quick_start?id=node)

 

위 코드를 간략하게 설명하자면,,,

 

  • source : 디자인 토큰이 저장된 장소
  • platforms : 디자인 토큰을 변환할 형태를 정의한 부분 (플랫폼 이름: 객체 형태)
    • 위 코드에선 scss라는 이름을 가지고 내부 속성에 따라 변환한다.
    • transformGroup : color, size, time 등 해당 속성들을 어떻게 변환할 껀지 한꺼번에 정의한 형태 
    • buildPath : 어디에 변환되어 저장될 건지
    • files
      • destination : 변환될 파일 이름
      • format: 변환될 형태를 정의한 포맷

 

 

 

Style Dictionary 공식 문서를 살펴보면 모든 속성에 대해 아주 자세하게 설명되어 있으니 참고하시길..

https://amzn.github.io/style-dictionary/#/

 

Style Dictionary - Style once, use everywhere. A build system for creating cross-platform styles.

 

amzn.github.io

 

 

 

우리는 bootstrap token을 css변수 형태로 변환할 꺼니까 아래처럼 코드를 수정해준다.

const StyleDictionaryExtended = require('style-dictionary').extend({
    source: ['./bootstrap-token.json'], 
    platforms: {
        css: {
            transformGroup: 'css',
            buildPath: 'build/',
            files: [{
                destination: 'variables.css',
                format: 'css/variables'
            }]
        }
        // ...
    }
});

StyleDictionaryExtended.buildAllPlatforms();

transformToken.js을 실행해주면 ! ($ node transformToken.js)

 

 

 

build/css/variables.css파일이 생성된다.

/**
 * Do not edit directly
 * Generated on Sat, 23 Sep 2023 08:47:51 GMT
 */

:root {
  --color-primary-color: #7749f8;
  --color-primary-color-dark: #5227cc;
  --color-primary-light: #ebe5fc;
  --color-secondary-color: #6c757d;
  --color-secondary-dark-color: #54595e;
  --color-secondary-light-color: #abb5be;
  --color-status-color-success: #28a745;
  --color-status-color-danger: #dc3545;
  --color-status-color-warning: #ffc107;
  --color-status-color-info: #17a2b8;
  --color-gray-100: #f8f9fa;
  ...
}

style dictionary가 정의해둔 포맷으로 변환되어 나온다.

 

하지만 우리는 이 포맷이 아니라, 우리가 원하는 형태로 포맷팅하여 변환할 것이다. 

 

 

4. 실습) 변수이름 바꾸기 (RegisterFormat)

 

변수 이름을 바꿀려면 Styledictionary.registerFormat 메서드를 이용을 해야한다.

https://amzn.github.io/style-dictionary/#/api?id=registerformat 

 

Style Dictionary - Style once, use everywhere. A build system for creating cross-platform styles.

 

amzn.github.io

StyleDictionary.registerFormat({
  name: 'json',
  formatter: function({dictionary, platform, options, file}) {
    return JSON.stringify(dictionary.tokens, null, 2);
  }
})

위 형태는 style dictionary의  registerFormat 사용 예제이다.

  • name : config에 작성한 format 값에 들어갈 이름 (해당 이름을 참조하게 됨)
  • formatter: 우리가 변환할 형태를 커스텀할 수 있는 부분, return하는 내용으로 결과물에 보이게 된다.

 

 

그러면 이제 대충 사용법을 알았으니, CSS 변수 이름을 바꿔보자!

--color-primary-colorprimary로 보일 수 있게 formatter을 정의할 것이다.

 

 

그러면, 우리의 customFormatter을 작성해보자

const StyleDictionary = require('style-dictionary');

StyleDictionary.registerFormat({
    name: 'customCss',
    formatter: ({dictionary, options}) => {
        console.log(dictionary);
        return "";
    },
});

 

위 형태로 작성해주고, 우리가 아까 작성한 StyleDictionaryExtended의 format 이름을 customCss로 바꿔주자

(css/variables -> customCss)

 

그리고, 다시 TransformToken.js를 실행시켜주면?

styleDictionary가 파싱한 형태의 dictionary를 볼 수 있다. 

 

styledictionary.allProperties의 내용을 보면, styledictionary가 변수이름을 어떻게 설정했는지 알 수 있다.

{
    description: '',
    type: 'color',
    value: '#7749f8',
    blendMode: 'normal',
    extensions: { 'org.lukasoppermann.figmaDesignTokens': [Object] },
    filePath: './bootstrap-token.json',
    isSource: true,
    original: {
      description: '',
      type: 'color',
      value: '#7749f8ff',
      blendMode: 'normal',
      extensions: [Object]
    },
    name: 'color-primary-color',
    attributes: { category: 'color', type: 'primary', item: 'color' },
    path: [ 'color', 'primary', 'color' ]
  },

 

name과 path 속성을 보면, styledictionary에서는 단순히 변수이름을 path를 케밥케이스로 이어준 것이라는 걸 확인할 수 있다.

 

그러면, 우리가 primary라는 key 이름을 얻을려면, path 배열에서 color를 제외하고 케밥 케이스로 이어주면 되겠다.

그리고 value는 StyleDictionary가 잘 파싱하여 value라는 속성에 color값을 잘 넣어주었기에 해당 값을 활용하면 된다.

 

 

위 내용 바탕으로, registerFormat을 정의해주자.

StyleDictionary.registerFormat({
    name: 'customCss',
    formatter: function({dictionary, platform, options, file}) {
        const variablesObject = dictionary.allProperties.reduce((acc,{value,type,  path}) => {
            // type에 따라 어떻게 파싱할 껀지 처리 해주면 됨 ! (현재는 color에 대해서만 파싱)
            if(type === 'color') {
                const key = path
                              .map((name) => name.replace('color', '').trim())
                              .filter((name) => name.length !== 0).join("-");
                acc[key] = value;
            }
            return acc;
        }, {});

        const cssString = Object.entries(variablesObject)
            .map(([key, value]) => `  --${key}: ${value};`)
            .join("\n");

        return `:root {\n${cssString}\n}`;
    }
})

 

사실 파싱로직을 작성하는 건 알고리즘?문제 푸는거랑 비슷한거라...

자신이 알아서 어떤 형태로 나오게 할건지 정의하면 된다.

 

 

위 형태로 정의한 registerFormat을 이용해 styleDictionary를 실행시켜주면,

:root {
  --primary: #7749f8;
  --primary-dark: #5227cc;
  --primary-light: #ebe5fc;
  --secondary: #6c757d;
  --secondary-dark: #54595e;
  --secondary-light: #abb5be;
  --status-success: #28a745;
  ...
}

 

이런 형태로 파싱되어 나오게 된다. !

 

 

 

registerFormat외에도,

https://amzn.github.io/style-dictionary/#/api

 

Style Dictionary - Style once, use everywhere. A build system for creating cross-platform styles.

 

amzn.github.io

해당 api 문서를 보면, 파일 헤더를 정의하거나 템플릿을 정의한다던가 등의 action이 가능하다.

 

 

그리고 우리가 처음 bootStrap 피그마에서 디자인 토큰을 추출한 플러그인 깃헙에 가보면

https://github.com/lukasoppermann/design-tokens/blob/main/examples/build.js 

StyleDictionary를 이용한 예제 코드들이 있다.

 

코드들을 참고해서, 어떤 형태로 파싱코드를 작성하는지 참고 할 수있다!

 

 

 

 

 

 

 

이번 글은 여기 까지 !!!!

궁금한 점 있으면 언제든지 댓글 달아주세요 :)

 

 

728x90