Skip to content

Commit 331c1f3

Browse files
committed
lots of updates!
- new output format - updated typescript types - updated readme - prettier formating
1 parent f1b6975 commit 331c1f3

6 files changed

Lines changed: 118 additions & 34 deletions

File tree

‎README.md‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,17 @@ It also comes with a snazzy CLI:
1010

1111
[This example site](https://tiltshift.github.io/figmint/) shows a figma file above html and css generated using the JSON that figmint outputs. This example can be found and run in the `example` folder in this repo.
1212

13+
👩🏽‍🏫*Recommendations*:
14+
15+
- Use names in figma that work well in javascript. `darkGreen` vs. `Dark Green`
16+
- Figma lets you name two styles the same thing. This will cause overwrite issues in your exports.
17+
1318
🚨*Notes*:
1419

1520
- Currently only Fill styles, Text styles, and exports are supported. PR's welcome for Grid and Effect styles!
1621
- Figmint will only pick up a style if it is used in the file you pass it. If you are finding a style isn't syncing make sure an element in the file is using that style.
17-
- Exports work only with with scale values (2x for example) and not with width or height values (512w). This is a limitation of the figma API.
22+
- PNG and JPG exports work only with with scale values (2x for example) and not with width or height values (512w). This is a limitation of the figma API.
23+
- Color styles with multiple properties are available as part of the raw export. The simpler named exports will only display the final property.
1824

1925
## Install and Config
2026

@@ -88,13 +94,13 @@ You can connect the example to your own figma file by editing `.figmintrc.json`
8894

8995
The CLI for figmint is pretty simple, just run `yarn figmint` or `npm run figmint` in your project after it is installed.
9096

91-
### Watch Mode
97+
### Watch Mode (alpha)
9298

9399
It is also possible to run the CLI in watch mode. This will update your json as things change on figma without you needing to re-run the command.
94100

95101
🚨*Notes*:
96102

97-
- Currently watch mode will overrite your Figma file every second. Depending on your dev enviroment this may cause your site to reload more than expected. Ideally figmint would only write files that have chagned. PR's welcome!
103+
- Currently watch mode will overrite the output every second. Depending on your dev enviroment this may cause your site to reload more than expected. Ideally figmint would only write files that have chagned. PR's welcome!
98104

99105
## Config format
100106

‎package.json‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,14 @@
2828
},
2929
"dependencies": {
3030
"figma-js": "^1.9.0",
31+
"rimraf": "^3.0.0",
3132
"utils": "^0.3.1"
3233
},
3334
"devDependencies": {
3435
"@types/node": "^12.12.21",
3536
"@types/react": "^16.9.17",
37+
"@types/rimraf": "^2.0.3",
38+
"@types/prettier": "^1.19.0",
3639
"@types/tinycolor2": "^1.4.2",
3740
"@typescript-eslint/eslint-plugin": "2.x",
3841
"@typescript-eslint/parser": "2.x",

‎src/index.tsx‎

Lines changed: 63 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ import { cosmiconfig } from 'cosmiconfig'
88
import fs from 'fs'
99
import path from 'path'
1010
import util from 'util'
11+
import rimraf from 'rimraf'
12+
13+
import prettier from 'prettier'
1114

1215
import { Text, Box, Color, render } from 'ink'
1316

@@ -24,6 +27,8 @@ import {
2427
FigmintExportType,
2528
downloadImage,
2629
PartialFigmintExportType,
30+
FigmintGradient,
31+
BaseTypeStyleType,
2732
} from './utils'
2833
import { exportFormatOptions } from 'figma-js'
2934

@@ -89,6 +94,15 @@ const Output = () => {
8994
const fetchAndAddImageUrls = React.useCallback(
9095
async (downloadLists: DownloadListType, finalExports: FinalExportsType) => {
9196
if (client && file) {
97+
const baseDirectory = path.join(output, 'exports')
98+
99+
// Clear out the output dir if it already exists
100+
if (fs.existsSync(baseDirectory)) {
101+
rimraf.sync(baseDirectory)
102+
}
103+
104+
fs.mkdirSync(baseDirectory, { recursive: true })
105+
92106
await Promise.all(
93107
Object.keys(downloadLists).map(async (format) => {
94108
if (downloadLists[format].length > 0) {
@@ -116,7 +130,7 @@ const Output = () => {
116130

117131
if (image) {
118132
// store images based on group
119-
const outDirectory = path.join(output, 'exports', image.group)
133+
const outDirectory = path.join(baseDirectory, image.group)
120134

121135
// image file name based on format and scale
122136
const outFile = `${image.name}${
@@ -258,49 +272,75 @@ const Output = () => {
258272

259273
// write out our file
260274

261-
let solidColors = ''
262-
let fillNames = ''
263-
let textNames = ''
275+
let colors = {} as { [colorName: string]: string }
276+
let gradients = {} as { [gradientName: string]: FigmintGradient }
277+
let imageFills = {} as { [imageFillName: string]: string }
278+
let textStyles = {} as { [name: string]: BaseTypeStyleType }
264279

265280
styles.fillStyles.forEach((fill) => {
266-
fillNames += `| '${fill.name}'`
267281
fill.styles.forEach((style) => {
268-
if (style.type === 'SOLID') {
269-
solidColors += `| '${style.color}'`
282+
switch (style.type) {
283+
case 'SOLID':
284+
colors[fill.name] = style.color
285+
break
286+
case 'GRADIENT_LINEAR':
287+
case 'GRADIENT_RADIAL':
288+
case 'GRADIENT_ANGULAR':
289+
case 'GRADIENT_DIAMOND':
290+
gradients[fill.name] = style
291+
break
292+
case 'IMAGE':
293+
imageFills[fill.name] = style.fileName
270294
}
271295
})
272296
})
273297

274298
styles.textStyles.forEach((text) => {
275-
textNames += `| '${text.name}'`
299+
textStyles[text.name] = text.styles
276300
})
277301

302+
const options = await prettier.resolveConfig(output)
303+
278304
fs.writeFileSync(
279305
path.join(output, `index.${typescript ? 'ts' : 'js'}`),
280-
`
281-
${typescript ? `import { FigmintOutput } from 'figmint'` : ''}
282-
283-
const styles${typescript ? ': FigmintOutput' : ''} = ${util.inspect(
284-
styles,
285-
{
286-
depth: Infinity,
287-
compact: false,
288-
},
289-
)}
306+
prettier.format(
307+
`
308+
const styles = {
309+
colors: ${util.inspect(colors, {
310+
depth: Infinity,
311+
compact: false,
312+
})},
313+
gradients: ${util.inspect(gradients, {
314+
depth: Infinity,
315+
compact: false,
316+
})},
317+
imageFills: ${util.inspect(imageFills, {
318+
depth: Infinity,
319+
compact: false,
320+
})},
321+
textStyles: ${util.inspect(textStyles, {
322+
depth: Infinity,
323+
compact: false,
324+
})},
325+
raw: ${util.inspect(styles, {
326+
depth: Infinity,
327+
compact: false,
328+
})},
329+
}${typescript ? ' as const' : ''}
290330
291331
${
292332
typescript
293333
? `
294-
${
295-
solidColors !== '' ? `export type SolidColors = ${solidColors}` : ''
296-
}
297-
${fillNames !== '' ? `export type FillNames = ${fillNames}` : ''}
298-
${textNames !== '' ? `export type TextNames = ${textNames}` : ''}
334+
export type ColorValues = keyof typeof styles.colors
335+
export type GradientValues = keyof typeof styles.gradients
336+
export type TextValues = keyof typeof styles.textStyles
299337
`
300338
: ''
301339
}
302340
303341
export default styles`,
342+
{ ...options, parser: typescript ? 'typescript' : 'babel' },
343+
),
304344
)
305345

306346
setLoading(false)

‎src/utils/downloadImages.ts‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ export const downloadImage = function(url: string, outFile: string) {
2222
})
2323
}
2424

25-
export const downloadFillImage = (image: ImageFill, outputDir: string) => {
25+
export const downloadFillImage = (
26+
image: ImageFill,
27+
outputDirectory: string,
28+
) => {
2629
return new Promise<string>((resolve) => {
2730
// figure out the file type
2831
https.get(image.url, (response) => {
@@ -34,15 +37,13 @@ export const downloadFillImage = (image: ImageFill, outputDir: string) => {
3437

3538
// once we know the file type write the file
3639
if (imageExt) {
37-
const imageFillDir = path.join(outputDir, 'fillImages')
38-
3940
// make sure the fillImages directory exists
40-
if (!fs.existsSync(imageFillDir)) {
41-
fs.mkdirSync(imageFillDir, { recursive: true })
41+
if (!fs.existsSync(outputDirectory)) {
42+
fs.mkdirSync(outputDirectory, { recursive: true })
4243
}
4344

4445
const outFile = path.join(
45-
imageFillDir,
46+
outputDirectory,
4647
`${image.imageRef}.${imageExt.ext}`,
4748
)
4849

‎src/utils/getStylesFromFile.ts‎

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
import fs from 'fs'
2+
import path from 'path'
3+
import rimraf from 'rimraf'
4+
15
import * as Figma from 'figma-js'
26

37
import { RawStyleObject, RawStyleType, ExportsObject } from './'
@@ -19,6 +23,16 @@ export const getStylesFromFile = async (
1923
let fileName: string | undefined
2024

2125
// download fill images
26+
27+
const outputDir = path.join(output, 'fillImages')
28+
29+
// Clear out the output dir if it already exists
30+
if (fs.existsSync(outputDir)) {
31+
rimraf.sync(outputDir)
32+
}
33+
34+
fs.mkdirSync(outputDir, { recursive: true })
35+
2236
for (const [key, style] of Object.entries(styleValues)) {
2337
// if we're an image fill grab the image url
2438
if (file.styles[key].styleType === 'FILL') {
@@ -31,7 +45,7 @@ export const getStylesFromFile = async (
3145
imageRef: fill.imageRef,
3246
url: imageFills.meta.images[fill.imageRef],
3347
},
34-
output,
48+
outputDir,
3549
)
3650
}
3751
}

‎yarn.lock‎

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -877,7 +877,7 @@
877877
resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7"
878878
integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==
879879

880-
"@types/glob@^7.1.1":
880+
"@types/glob@*", "@types/glob@^7.1.1":
881881
version "7.1.1"
882882
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575"
883883
integrity sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==
@@ -916,6 +916,11 @@
916916
resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
917917
integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==
918918

919+
"@types/prettier@^1.19.0":
920+
version "1.19.0"
921+
resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-1.19.0.tgz#a2502fb7ce9b6626fdbfc2e2a496f472de1bdd05"
922+
integrity sha512-gDE8JJEygpay7IjA/u3JiIURvwZW08f0cZSZLAzFoX/ZmeqvS0Sqv+97aKuHpNsalAMMhwPe+iAS6fQbfmbt7A==
923+
919924
"@types/prop-types@*":
920925
version "15.7.1"
921926
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.1.tgz#f1a11e7babb0c3cad68100be381d1e064c68f1f6"
@@ -934,6 +939,14 @@
934939
"@types/prop-types" "*"
935940
csstype "^2.2.0"
936941

942+
"@types/rimraf@^2.0.3":
943+
version "2.0.3"
944+
resolved "https://registry.yarnpkg.com/@types/rimraf/-/rimraf-2.0.3.tgz#0199a46af106729ba14213fda7b981278d8c84f2"
945+
integrity sha512-dZfyfL/u9l/oi984hEXdmAjX3JHry7TLWw43u1HQ8HhPv6KtfxnrZ3T/bleJ0GEvnk9t5sM7eePkgMqz3yBcGg==
946+
dependencies:
947+
"@types/glob" "*"
948+
"@types/node" "*"
949+
937950
"@types/tinycolor2@^1.4.0", "@types/tinycolor2@^1.4.2":
938951
version "1.4.2"
939952
resolved "https://registry.yarnpkg.com/@types/tinycolor2/-/tinycolor2-1.4.2.tgz#721ca5c5d1a2988b4a886e35c2ffc5735b6afbdf"
@@ -6390,6 +6403,13 @@ rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3:
63906403
dependencies:
63916404
glob "^7.1.3"
63926405

6406+
rimraf@^3.0.0:
6407+
version "3.0.0"
6408+
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.0.tgz#614176d4b3010b75e5c390eb0ee96f6dc0cebb9b"
6409+
integrity sha512-NDGVxTsjqfunkds7CqsOiEnxln4Bo7Nddl3XhS4pXg5OzwkLqJ971ZVAAnB+DDLnF76N+VnDEiBHaVV8I06SUg==
6410+
dependencies:
6411+
glob "^7.1.3"
6412+
63936413
ripemd160@^2.0.0, ripemd160@^2.0.1:
63946414
version "2.0.2"
63956415
resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c"

0 commit comments

Comments
 (0)