├── .gitignore ├── package.json ├── output ├── dark.css ├── light.css └── global.css ├── README.md ├── tokens ├── input.json ├── dark.json ├── light.json └── global.json ├── .github └── workflows │ └── create-tokens.yml ├── LICENSE └── tokens.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": {}, 6 | "dependencies": { 7 | "style-dictionary": "^3.0.2" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /output/dark.css: -------------------------------------------------------------------------------- 1 | .dark-theme { 2 | --theme-bg-default: #171717; 3 | --theme-bg-subtle: #323232; 4 | --theme-bg-muted: #757575; 5 | --theme-fg-default: #ffffff; 6 | --theme-fg-on-accent: #ffffff; 7 | --theme-fg-muted: #eeeeee; 8 | --theme-fg-subtle: #9e9e9e; 9 | --theme-accent-default: #3d53f5; 10 | --theme-accent-subtle: #060818; 11 | } -------------------------------------------------------------------------------- /output/light.css: -------------------------------------------------------------------------------- 1 | .light-theme { 2 | --theme-bg-default: #ffffff; 3 | --theme-bg-subtle: #f5f5f5; 4 | --theme-bg-muted: #e0e0e0; 5 | --theme-fg-default: #171717; 6 | --theme-fg-on-accent: #ffffff; 7 | --theme-fg-muted: #616161; 8 | --theme-fg-subtle: #9e9e9e; 9 | --theme-accent-default: #3d53f5; 10 | --theme-accent-subtle: #eceefe; 11 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # figma-tokens-example-multi 2 | 3 | This example illustrates how you can transform your tokens stored on Figma Tokens (with GitHub sync enabled) to be automatically transformed with token-transformer and Style Dictionary in a dark/light theme environment. 4 | 5 | Change your tokens in `tokens.json` (either directly or with the Figma Tokens plugin in Figma). The GitHub action will automatically generate tokens to the `tokens/` directory that can then be read by Style Dictionary, which will output tokens to the format you defined in `build.js` - css variables will be generated in the `output` directory. 6 | -------------------------------------------------------------------------------- /tokens/input.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors": { 3 | "red": { 4 | "300": { 5 | "value": "#FCA5A5", 6 | "type": "color" 7 | }, 8 | "500": { 9 | "value": "#EF4444", 10 | "type": "color" 11 | }, 12 | "700": { 13 | "value": "#B91C1C", 14 | "type": "color" 15 | } 16 | }, 17 | "black": { 18 | "value": "#000000", 19 | "type": "color" 20 | }, 21 | "white": { 22 | "value": "#ffffff", 23 | "type": "color" 24 | } 25 | }, 26 | "spacing": { 27 | "sm": { 28 | "value": 4, 29 | "type": "spacing" 30 | }, 31 | "md": { 32 | "value": 8, 33 | "type": "spacing" 34 | }, 35 | "lg": { 36 | "value": 16, 37 | "type": "spacing" 38 | }, 39 | "xl": { 40 | "value": 32, 41 | "type": "spacing" 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /tokens/dark.json: -------------------------------------------------------------------------------- 1 | { 2 | "theme": { 3 | "bg": { 4 | "default": { 5 | "value": "#171717", 6 | "type": "color" 7 | }, 8 | "subtle": { 9 | "value": "#323232", 10 | "type": "color" 11 | }, 12 | "muted": { 13 | "value": "#757575", 14 | "type": "color" 15 | } 16 | }, 17 | "fg": { 18 | "default": { 19 | "value": "#ffffff", 20 | "type": "color" 21 | }, 22 | "onAccent": { 23 | "value": "#ffffff", 24 | "type": "color" 25 | }, 26 | "muted": { 27 | "value": "#eeeeee", 28 | "type": "color" 29 | }, 30 | "subtle": { 31 | "value": "#9e9e9e", 32 | "type": "color" 33 | } 34 | }, 35 | "accent": { 36 | "default": { 37 | "value": "#3d53f5", 38 | "type": "color" 39 | }, 40 | "subtle": { 41 | "value": "#060818", 42 | "type": "color" 43 | } 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /tokens/light.json: -------------------------------------------------------------------------------- 1 | { 2 | "theme": { 3 | "bg": { 4 | "default": { 5 | "value": "#ffffff", 6 | "type": "color" 7 | }, 8 | "subtle": { 9 | "value": "#f5f5f5", 10 | "type": "color" 11 | }, 12 | "muted": { 13 | "value": "#e0e0e0", 14 | "type": "color" 15 | } 16 | }, 17 | "fg": { 18 | "default": { 19 | "value": "#171717", 20 | "type": "color" 21 | }, 22 | "onAccent": { 23 | "value": "#ffffff", 24 | "type": "color" 25 | }, 26 | "muted": { 27 | "value": "#616161", 28 | "type": "color" 29 | }, 30 | "subtle": { 31 | "value": "#9e9e9e", 32 | "type": "color" 33 | } 34 | }, 35 | "accent": { 36 | "default": { 37 | "value": "#3d53f5", 38 | "type": "color" 39 | }, 40 | "subtle": { 41 | "value": "#eceefe", 42 | "type": "color" 43 | } 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /.github/workflows/create-tokens.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: [push] 3 | 4 | jobs: 5 | build: 6 | runs-on: ubuntu-latest 7 | 8 | steps: 9 | - uses: actions/checkout@v2 10 | - name: Setup Node.js environment 11 | uses: actions/setup-node@v2.4.0 12 | # Install dependencies 13 | - run: npm install 14 | # Transform Figma Tokens JSON to something Style Dictionary can read 15 | - run: npx token-transformer tokens.json tokens/global.json global 16 | # Create a light theme, exclude the global tokens 17 | - run: npx token-transformer tokens.json tokens/light.json global,light,theme global 18 | # Create a dark theme, exclude the global tokens 19 | - run: npx token-transformer tokens.json tokens/dark.json global,dark,theme global 20 | # Convert tokens according to Style Dictionary config 21 | - run: node build.js 22 | # Add files that were created during a run, e.g. created files from style dictionary or token-transformer. 23 | - uses: stefanzweifel/git-auto-commit-action@v4 24 | with: 25 | commit_message: Update Tokens 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Jan Six 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /output/global.css: -------------------------------------------------------------------------------- 1 | .global-theme { 2 | --colors-black: #171717; 3 | --colors-white: #ffffff; 4 | --colors-red-50: #FFF5F7; 5 | --colors-red-100: #fce8ec; 6 | --colors-red-200: #f9d0d9; 7 | --colors-red-300: #f2a2b3; 8 | --colors-red-400: #e95c7b; 9 | --colors-red-500: #df1642; 10 | --colors-red-600: #9c0f2e; 11 | --colors-red-700: #59091a; 12 | --colors-red-800: #2d040d; 13 | --colors-red-900: #160207; 14 | --colors-red-950: #100105; 15 | --colors-blue-50: #eceefe; 16 | --colors-blue-100: #d8ddfd; 17 | --colors-blue-200: #b1bafb; 18 | --colors-blue-300: #8b98f9; 19 | --colors-blue-400: #6475f7; 20 | --colors-blue-500: #3d53f5; 21 | --colors-blue-600: #3142c4; 22 | --colors-blue-700: #253293; 23 | --colors-blue-800: #182162; 24 | --colors-blue-900: #0c1131; 25 | --colors-blue-950: #060818; 26 | --colors-grey-50: #fcfcfc; 27 | --colors-grey-100: #f5f5f5; 28 | --colors-grey-200: #eeeeee; 29 | --colors-grey-300: #e0e0e0; 30 | --colors-grey-400: #bdbdbd; 31 | --colors-grey-500: #9e9e9e; 32 | --colors-grey-600: #757575; 33 | --colors-grey-700: #616161; 34 | --colors-grey-800: #424242; 35 | --colors-grey-900: #323232; 36 | --colors-grey-950: #212121; 37 | } -------------------------------------------------------------------------------- /tokens/global.json: -------------------------------------------------------------------------------- 1 | { 2 | "_colors": { 3 | "black": { 4 | "value": "#171717", 5 | "type": "color" 6 | }, 7 | "white": { 8 | "value": "#ffffff", 9 | "type": "color" 10 | }, 11 | "red": { 12 | "50": { 13 | "value": "#FFF5F7", 14 | "type": "color" 15 | }, 16 | "100": { 17 | "value": "#fce8ec", 18 | "type": "color" 19 | }, 20 | "200": { 21 | "value": "#f9d0d9", 22 | "type": "color" 23 | }, 24 | "300": { 25 | "value": "#f2a2b3", 26 | "type": "color" 27 | }, 28 | "400": { 29 | "value": "#e95c7b", 30 | "type": "color" 31 | }, 32 | "500": { 33 | "value": "#df1642", 34 | "type": "color" 35 | }, 36 | "600": { 37 | "value": "#9c0f2e", 38 | "type": "color" 39 | }, 40 | "700": { 41 | "value": "#59091a", 42 | "type": "color" 43 | }, 44 | "800": { 45 | "value": "#2d040d", 46 | "type": "color" 47 | }, 48 | "900": { 49 | "value": "#160207", 50 | "type": "color" 51 | }, 52 | "950": { 53 | "value": "#100105", 54 | "type": "color" 55 | } 56 | }, 57 | "blue": { 58 | "50": { 59 | "value": "#eceefe", 60 | "type": "color" 61 | }, 62 | "100": { 63 | "value": "#d8ddfd", 64 | "type": "color" 65 | }, 66 | "200": { 67 | "value": "#b1bafb", 68 | "type": "color" 69 | }, 70 | "300": { 71 | "value": "#8b98f9", 72 | "type": "color" 73 | }, 74 | "400": { 75 | "value": "#6475f7", 76 | "type": "color" 77 | }, 78 | "500": { 79 | "value": "#3d53f5", 80 | "type": "color" 81 | }, 82 | "600": { 83 | "value": "#3142c4", 84 | "type": "color" 85 | }, 86 | "700": { 87 | "value": "#253293", 88 | "type": "color" 89 | }, 90 | "800": { 91 | "value": "#182162", 92 | "type": "color" 93 | }, 94 | "900": { 95 | "value": "#0c1131", 96 | "type": "color" 97 | }, 98 | "950": { 99 | "value": "#060818", 100 | "type": "color" 101 | } 102 | }, 103 | "grey": { 104 | "50": { 105 | "value": "#fcfcfc", 106 | "type": "color" 107 | }, 108 | "100": { 109 | "value": "#f5f5f5", 110 | "type": "color" 111 | }, 112 | "200": { 113 | "value": "#eeeeee", 114 | "type": "color" 115 | }, 116 | "300": { 117 | "value": "#e0e0e0", 118 | "type": "color" 119 | }, 120 | "400": { 121 | "value": "#bdbdbd", 122 | "type": "color" 123 | }, 124 | "500": { 125 | "value": "#9e9e9e", 126 | "type": "color" 127 | }, 128 | "600": { 129 | "value": "#757575", 130 | "type": "color" 131 | }, 132 | "700": { 133 | "value": "#616161", 134 | "type": "color" 135 | }, 136 | "800": { 137 | "value": "#424242", 138 | "type": "color" 139 | }, 140 | "900": { 141 | "value": "#323232", 142 | "type": "color" 143 | }, 144 | "950": { 145 | "value": "#212121", 146 | "type": "color" 147 | } 148 | } 149 | } 150 | } -------------------------------------------------------------------------------- /tokens.json: -------------------------------------------------------------------------------- 1 | { 2 | "global": { 3 | "_colors": { 4 | "black": { 5 | "value": "#171717", 6 | "type": "color" 7 | }, 8 | "white": { 9 | "value": "#ffffff", 10 | "type": "color" 11 | }, 12 | "red": { 13 | "50": { 14 | "value": "#FFF5F7", 15 | "type": "color" 16 | }, 17 | "100": { 18 | "value": "#fce8ec", 19 | "type": "color" 20 | }, 21 | "200": { 22 | "value": "#f9d0d9", 23 | "type": "color" 24 | }, 25 | "300": { 26 | "value": "#f2a2b3", 27 | "type": "color" 28 | }, 29 | "400": { 30 | "value": "#e95c7b", 31 | "type": "color" 32 | }, 33 | "500": { 34 | "value": "#df1642", 35 | "type": "color" 36 | }, 37 | "600": { 38 | "value": "#9c0f2e", 39 | "type": "color" 40 | }, 41 | "700": { 42 | "value": "#59091a", 43 | "type": "color" 44 | }, 45 | "800": { 46 | "value": "#2d040d", 47 | "type": "color" 48 | }, 49 | "900": { 50 | "value": "#160207", 51 | "type": "color" 52 | }, 53 | "950": { 54 | "value": "#100105", 55 | "type": "color" 56 | } 57 | }, 58 | "blue": { 59 | "50": { 60 | "value": "#eceefe", 61 | "type": "color" 62 | }, 63 | "100": { 64 | "value": "#d8ddfd", 65 | "type": "color" 66 | }, 67 | "200": { 68 | "value": "#b1bafb", 69 | "type": "color" 70 | }, 71 | "300": { 72 | "value": "#8b98f9", 73 | "type": "color" 74 | }, 75 | "400": { 76 | "value": "#6475f7", 77 | "type": "color" 78 | }, 79 | "500": { 80 | "value": "#3d53f5", 81 | "type": "color" 82 | }, 83 | "600": { 84 | "value": "#3142c4", 85 | "type": "color" 86 | }, 87 | "700": { 88 | "value": "#253293", 89 | "type": "color" 90 | }, 91 | "800": { 92 | "value": "#182162", 93 | "type": "color" 94 | }, 95 | "900": { 96 | "value": "#0c1131", 97 | "type": "color" 98 | }, 99 | "950": { 100 | "value": "#060818", 101 | "type": "color" 102 | } 103 | }, 104 | "grey": { 105 | "50": { 106 | "value": "#fcfcfc", 107 | "type": "color" 108 | }, 109 | "100": { 110 | "value": "#f5f5f5", 111 | "type": "color" 112 | }, 113 | "200": { 114 | "value": "#eeeeee", 115 | "type": "color" 116 | }, 117 | "300": { 118 | "value": "#e0e0e0", 119 | "type": "color" 120 | }, 121 | "400": { 122 | "value": "#bdbdbd", 123 | "type": "color" 124 | }, 125 | "500": { 126 | "value": "#9e9e9e", 127 | "type": "color" 128 | }, 129 | "600": { 130 | "value": "#757575", 131 | "type": "color" 132 | }, 133 | "700": { 134 | "value": "#616161", 135 | "type": "color" 136 | }, 137 | "800": { 138 | "value": "#424242", 139 | "type": "color" 140 | }, 141 | "900": { 142 | "value": "#323232", 143 | "type": "color" 144 | }, 145 | "950": { 146 | "value": "#212121", 147 | "type": "color" 148 | } 149 | } 150 | } 151 | }, 152 | "light": { 153 | "theme": { 154 | "bg": { 155 | "default": { 156 | "value": "{_colors.white}", 157 | "type": "color" 158 | }, 159 | "subtle": { 160 | "value": "{_colors.grey.100}", 161 | "type": "color" 162 | }, 163 | "muted": { 164 | "value": "{_colors.grey.300}", 165 | "type": "color" 166 | } 167 | }, 168 | "fg": { 169 | "default": { 170 | "value": "{_colors.black}", 171 | "type": "color" 172 | }, 173 | "onAccent": { 174 | "value": "{_colors.white}", 175 | "type": "color" 176 | }, 177 | "muted": { 178 | "value": "{_colors.grey.700}", 179 | "type": "color" 180 | }, 181 | "subtle": { 182 | "value": "{_colors.grey.500}", 183 | "type": "color" 184 | } 185 | }, 186 | "accent": { 187 | "default": { 188 | "value": "{_colors.blue.500}", 189 | "type": "color" 190 | }, 191 | "subtle": { 192 | "value": "{_colors.blue.50}", 193 | "type": "color" 194 | } 195 | } 196 | } 197 | }, 198 | "dark": { 199 | "theme": { 200 | "bg": { 201 | "default": { 202 | "value": "{_colors.black}", 203 | "type": "color" 204 | }, 205 | "subtle": { 206 | "value": "{_colors.grey.900}", 207 | "type": "color" 208 | }, 209 | "muted": { 210 | "value": "{_colors.grey.600}", 211 | "type": "color" 212 | } 213 | }, 214 | "fg": { 215 | "default": { 216 | "value": "{_colors.white}", 217 | "type": "color" 218 | }, 219 | "onAccent": { 220 | "value": "{_colors.white}", 221 | "type": "color" 222 | }, 223 | "muted": { 224 | "value": "{_colors.grey.200}", 225 | "type": "color" 226 | }, 227 | "subtle": { 228 | "value": "{_colors.grey.500}", 229 | "type": "color" 230 | } 231 | }, 232 | "accent": { 233 | "default": { 234 | "value": "{_colors.blue.500}", 235 | "type": "color" 236 | }, 237 | "subtle": { 238 | "value": "{_colors.blue.950}", 239 | "type": "color" 240 | } 241 | } 242 | } 243 | } 244 | } --------------------------------------------------------------------------------