radixUI colors 파일을 참고해서 css 모듈 만들기

    오늘 분석할 코드는 radixUI의 build-css-modules.js

    const fs = require("fs");
    const path = require("path");
    const allColorScales = require("../index");
    
    const outputDir = require("../tsconfig.json").compilerOptions.outDir;
    
    const supportsP3AtRule = "@supports (color: color(display-p3 1 1 1))";
    const matchesP3MediaRule = "@media (color-gamut: p3)";
    
    Object.keys(allColorScales)
      .filter((key) => !key.includes("P3"))
      .forEach((key) => {
        let selector = ":root, .light, .light-theme";
    
        if (key === "blackA" || key === "whiteA") {
          selector = ":root";
        }
    
        if (key.includes("Dark")) {
          selector = ".dark, .dark-theme";
        }
    
        const srgbValues = Object.entries(allColorScales).find(
          ([name]) => name === key
        )[1];
    
        const srgbCssProperties = Object.entries(srgbValues)
          .map(([name, value]) => [toCssCasing(name), value])
          .map(([name, value]) => `  --${name}: ${value};`)
          .join("\n");
    
        const srgbCssRule = `${selector} {\n${srgbCssProperties}\n}`;
    
        const p3Values = Object.entries(allColorScales).find(
          ([name]) => name === key + "P3" || name === key.replace(/.$/, "P3A")
        )[1];
    
        const p3CssProperties = Object.entries(p3Values)
          .map(([name, value]) => [toCssCasing(name), value])
          .map(([name, value]) => `      --${name}: ${value};`)
          .join("\n");
    
        let p3CssRule = `    ${selector} {\n${p3CssProperties}\n    }`;
        p3CssRule = `  ${matchesP3MediaRule} {\n${p3CssRule}\n  }`;
        p3CssRule = `${supportsP3AtRule} {\n${p3CssRule}\n}`;
    
        fs.writeFileSync(
          path.join(outputDir, toFileName(key) + ".css"),
          `${srgbCssRule}\n\n${p3CssRule}`
        );
      });
    
    function toCssCasing(str) {
      return str
        .replace(/([a-z])(\d)/, "$1-$2")
        .replace(/([A-Z])/g, "-$1")
        .toLowerCase();
    }
    
    function toFileName(str) {
      return toCssCasing(str).replace(/-a$/, "-alpha");
    }

     

    위 코드는 radixUI의 colors 레포지토리의 코드이다.

    ts로 작성된 컬러 객체를 css로 변환하기 위해 사용하는 코드로 추정된다.

    변수 이름에도 들어가 있고, 속성 값으로도 들어가있는 p3는 어떤 걸 의미하는지 아직 잘 모르겠다.

     

     

     

    P3가 도대체 뭘까.. key에 P3가 있는 값을 먼저 찾아보기로 했다.

     

     

     

    display-p3를 보니 애플이 만든 DPI-P3를 의미하는 거였다.

    그렇다면, css에 display-p3라는 속성이 있는건가.. 찾아보니 MDN에서 color-gamut라는 문서를 찾을 수 있었다.

    코덕들이 '하늘 아래 같은 색 없다'하던데 문득 그 말이 떠올랐다. ㅋㅋ

    저 color-gamut 속성을 쓰면 같은 화이트도 색 공간에 따라 표현이 다르다는 건데, 써본 적이 없어서 진짜 다른지 궁금하긴 하다.

     

    아무튼, 궁금증을 해결했으니 다시 본론으로 돌아가보자.

     

     

     

    DPI-P3 색상이 아닌 key만 필터링 해서 한번 더 반복문을 돌리고 있다. 

    여기서는 셀렉터를 만들어주는 변수가 있고, key 값이 어떤 거냐에 따라 selector의 종류를 만들어 주고 있었다.

     

    다른 코드도 비슷한 형태로 css 셀렉터 이름을 만들어 주거나, fs 모듈을 사용해서 css 파일을 생성하는 코드로 이루어져 있었는데,

    실제 build된 파일을 살펴보고 결과물하고 코드랑 같이 보면 더 이해하기 좋을 것 같아서 빌드 후 결과물을 확인해보았다.

     

     

    빌드하면 내부는 위와 같은 코드를 가진 css 파일이 생성된다.

     

    [컬러].css

    [컬러]-alpha.css

    [컬러]-dark-alpha.css

    [컬러]-dark.css

     

    이런식으로 컬러 이름 하나당 총 4개의 css 파일이 생성된다.

     

     

    이제 대충 파악 완료 됐으니 유사하게 따라해보자.

    작게 시작하는 게 좋을 것 같으므로 light.ts 파일을 만든 후, 컬러 한 가지를 선택해 10개의 색상과 radix colors와 동일하게

    기본, 기본 알파, 기본 P3, 기본 P3 알파 총 4종류(40개)를 정의해볼 것이다.

     

    radix와 똑같은 색상 값을 써도 되겠지만, AI에게 시켜서 새 컬러를 만들 생각이다.

    개인적으로 숫자 값은 100단위를 좋아하므로 100단위로 생성했다.

     

     

     

    세레니티 컬러 기본 값을 기준으로 색상 코드를 만들어 오도록 했는데,

    결과가 마음에 안들어서 몇 번의 매질 끝에 색상 값을 만들었다. 색상이라 그런지 생성하는데 시간이 좀 걸린다.

    P3값은 제대로 만들어졌는지 모르겠다 ㅋㅋㅋ

     

     

    css도 radix와 유사한 형태로 만들 예정

     

    이제 이렇게 css 파일을 만들 수 있도록 코드를 짜보겠다.

     

    CSS 파일 만드는 로직 작성

    먼저 serenity100 이 key값으로 들어오면  serenity-100와 같은 형태로 변경시키는 부분부터 작성하는 것을 시작으로 css 파일을 생성하는 로직을 작성했다. (지금은 P3는 제외하고 기본 컬러와 기본 알파 컬러 값만 css로 변환하는 로직을 작성했다.)

     

    처음에 radix 로직 왜 이렇게 복잡하게 때려넣어놨지..생각했는데 직접 해보니 이해할 수 있었다..ㅋㅋ

    (생각 이상으로 복잡하더라....😥 최대한 모듈 단위로 기능을 나눠서 짜려고 하긴 했는데 SRP를 조금씩 위배하고 있는 모습이....)

    radix 코드를 참고하며 작성해본 코드

     

     

    package.json에 스크립트 세팅하기 전에 제대로 동작하는지 확인해봤다.

     

     

     

     

    node 명령어를 사용하여 css 모듈이 원하는 파일 명으로 생성되었다.

    이제 css 셀렉터와 프로퍼티도 제대로 들어갔는지 확인해보자.

     

     

     

     

    아주 잘 추가되었다. 🥰

    P3는 서포트랑 미디어 쿼리도 추가해줘야 하므로 추가 로직을 더 작성해주면 된다.

     

    큰 틀의 로직은 대략 이해했으니 나머지 추가 로직을 넣는 건 (복잡할 수는 있어도) 어렵지는 않을 것 같다.

    나만의 컬러 팔레트 만들어서 라이브러리로 써보는 것도 괜찮을 것 같다는 생각이다.

    댓글