Transform json into scss class with style-dictionary

591 Views Asked by At

I’m trying to define a custom format in style-dictionary that would output scss classes for every typography. But I am getting [object, object] instead of a scss class.

base.json with my tokens

{
  "fontFamilies": {
    "default": {
      "value": "Inter",
      "type": "fontFamily"
    }
  },
  "weights": {
    "bold": {
      "value": "Bold",
      "type": "fontWeight"
    }
  },
  "sizes": {
    "sm": {
      "value": "12",
      "type": "fontSize"
    },
    "md": {
      "value": "16",
      "type": "fontSize"
    },
    "lg": {
      "value": "24",
      "type": "fontSize"
    },
    "xl": {
      "value": "32",
      "type": "fontSize"
    }
  },
  "ls": {
    "headlines": {
      "value": "-1%",
      "type": "letterSpacing"
    },
    "body": {
      "value": "0%",
      "type": "letterSpacing"
    }
  },
  "lh": {
    "headlines": {
      "value": "110%",
      "type": "lineHeight"
    },
    "body": {
      "value": "140%",
      "type": "lineHeight"
    }
  },
  "headlines": {
    "large": {
      "value": {
        "fontFamily": "{fontFamilies.default}",
        "fontWeight": "{weights.bold}",
        "fontSize": "{sizes.xl}",
        "letterSpacing": "{ls.headlines}",
        "lineHeight": "{lh.headlines}"
      },
      "type": "typography"
    },
    "small": {
      "value": {
        "fontFamily": "{fontFamilies.default}",
        "fontWeight": "{weights.bold}",
        "fontSize": "{sizes.lg}",
        "letterSpacing": "{ls.headlines}",
        "lineHeight": "{lh.headlines}"
      },
      "type": "typography"
    }
  },
  "body": {
    "large": {
      "value": {
        "fontFamily": "{fontFamilies.default}",
        "fontWeight": "{weights.bold}",
        "fontSize": "{sizes.md}",
        "letterSpacing": "{ls.body}",
        "lineHeight": "{lh.body}"
      },
      "type": "typography"
    },
    "small": {
      "value": {
        "fontFamily": "{fontFamilies.default}",
        "fontWeight": "{weights.bold}",
        "fontSize": "{sizes.sm}",
        "letterSpacing": "{ls.body}",
        "lineHeight": "{lh.body}"
      },
      "type": "typography"
    }
  }
}

The output in _variables.scss

$font-families-default: Inter;
$weights-bold: Bold;
$sizes-sm: 12;
$sizes-md: 16;
$sizes-lg: 24;
$sizes-xl: 32;
$ls-headlines: -1%;
$ls-body: 0%;
$lh-headlines: 110%;
$lh-body: 140%;
$headlines-large: [object Object];
$headlines-small: [object Object];
$body-large: [object Object];
$body-small: [object Object];

The desired result is:

$font-families-default: Inter;
$weights-bold: Bold;
$sizes-sm: 12;
$sizes-md: 16;
$sizes-lg: 24;
$sizes-xl: 32;
$ls-headlines: -1%;
$ls-body: 0%;
$lh-headlines: 110%;
$lh-body: 140%;
    .headlines-large {
      font-family: Inter;
      font-size: 32 ;
      font-weight: Bold;
      line-height: 110%;
    }

I don't know if my config.json and build.js files are ok

build.js

const StyleDictionary = require('style-dictionary').extend('config.json');

  StyleDictionary.registerFormat({
    name: 'css/classFormat',
    formatter: function (dictionary, config) {
      return `
  ${dictionary.allProperties
    .map((prop) => {
      return `
  .${prop.name} {
      font-family: ${prop.value.fontFamily},
      font-size: ${prop.value.fontSize},
      font-weight: ${prop.value.fontWeight},
      line-height: ${prop.value.lineHeight}
  };`})
    .join('\n')}
  `
    },
  })


StyleDictionary.buildAllPlatforms();

package.json

{
  "name": "mytokens",
  "version": "1.0.0",
  "description": "This example code is bare-bones to show you what this framework can do. If you have the style-dictionary module installed globally, you can `cd` into this directory and run: ```bash style-dictionary build ```",
  "main": "index.js",
  "scripts": {
    "build": "node ./build.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
1

There are 1 best solutions below

0
On

Unfortunately cannot test this locally currently, but I would suggest trying to wrap your return in JSON.stringify(), to see if the returned stringified object is what you've intended it to be. That way you'd be able to expand your debugging process. Something like this:

  StyleDictionary.registerFormat({
   name: 'css/classFormat',
   formatter: function (dictionary, config) {
    const returnedValue = `
    ${dictionary.allProperties
    .map((prop) => {
     return `
    .${prop.name} {
    font-family: ${prop.value.fontFamily},
    font-size: ${prop.value.fontSize},
    font-weight: ${prop.value.fontWeight},
    line-height: ${prop.value.lineHeight}
      };`}).join('\n')}`;
     return JSON.stringify(returnedValue);
      },
    })