Skip to content

Commit

Permalink
feat: add css export to nodes
Browse files Browse the repository at this point in the history
re #19
  • Loading branch information
braposo committed Jun 4, 2019
1 parent 15fcfa8 commit 08200a8
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 34 deletions.
20 changes: 0 additions & 20 deletions src/types/css.ts

This file was deleted.

12 changes: 12 additions & 0 deletions src/types/helpers/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,18 @@ export const type = gql`
# gradient stop position
position: Float
}
enum ColorMode {
RGB
HEX
HSL
}
`;

export enum ColorMode {
RGB,
HEX,
HSL,
}

export const resolvers = {};
39 changes: 25 additions & 14 deletions src/types/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { createBatchResolver } from "graphql-resolve-batch";
import camelCase from "lodash/camelCase";
import groupBy from "lodash/groupBy";
import { loadImages } from "../utils/figma";
import { generateCSS } from "../utils/helpers";

export const nodeProperties = `
# A string uniquely identifying this node within the document.
Expand All @@ -18,7 +19,7 @@ export const nodeProperties = `
type: NodeType!
# Additional properties
image(params: ImageNodeParams): Image
export(params: ExportParams): String
`;

export const nodeTypes = [
Expand Down Expand Up @@ -60,21 +61,31 @@ export const resolvers = {

return capitalise(camelCase(nodeType));
},
image: createBatchResolver<any, any>(async (sources, { params }) => {
export: createBatchResolver<any, any>(async (sources, { params }) => {
const sourcesByFile = groupBy(sources, "fileId");
const parsedImages = await Promise.all(
Object.entries(sourcesByFile).map(([fileId, nodes]) =>
loadImages(fileId, { ...params, ids: nodes.map(({ id }) => id) }).then(
({ images }) => images
)
)
);

return parsedImages.reduce(
(acc: any[], parsedImage) => [
...acc,
...Object.entries(parsedImage).map(entry => ({ id: entry[0], file: entry[1] })),
],
const fileExports =
params && params.format === "css"
? Object.entries(sourcesByFile).map(([fileId, nodes]) =>
nodes.reduce(
(acc, node) => ({
...acc,
[node.id]: generateCSS(node),
}),
{}
)
)
: await Promise.all(
Object.entries(sourcesByFile).map(([fileId, nodes]) =>
loadImages(fileId, {
...params,
ids: nodes.map(({ id }) => id),
}).then(({ images }) => images)
)
);

return fileExports.reduce(
(acc: any[], parsedImage) => [...acc, ...Object.values(parsedImage)],
[]
);
}),
Expand Down
34 changes: 34 additions & 0 deletions src/utils/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { Color } from "figma-js";
import { ColorMode } from "../types/helpers/style";

export const getPosition = node => ({
x: node.absoluteBoundingBox.x,
y: node.absoluteBoundingBox.y,
Expand All @@ -7,3 +10,34 @@ export const getSize = node => ({
width: node.absoluteBoundingBox.width,
height: node.absoluteBoundingBox.height,
});

export const addUnit = (string?: string | number, unit: string = "px") =>
string != null ? `${string}${unit}` : string;

export const getColor = ({ r, g, b, a }: Color, mode: ColorMode) => `rgba(${r}, ${g}, ${b}, ${a})`;

export const JSToCSS = cssObject => {
return Object.entries(cssObject)
.map(([key, value]) => {
if (value == null) {
return value;
}

return `${key.replace(/([A-Z])/g, g => `-${g[0].toLowerCase()}`)}: ${value};`;
})
.filter(Boolean)
.join(" ");
};

export const generateCSS = node => {
const styles = {
textAlign: node.style && node.style.textAlignHorizontal.toLowerCase(),
verticalAlign: node.style && node.style.textAlignVertical.toLowerCase(),
lineHeight: node.style && addUnit(node.style.lineHeightPx),
width: node.absoluteBoundingBox && addUnit(node.absoluteBoundingBox.width),
height: node.absoluteBoundingBox && addUnit(node.absoluteBoundingBox.height),
backgroundColor: node.backgroundColor && getColor(node.backgroundColor, ColorMode.RGB),
};

return JSToCSS(styles);
};

0 comments on commit 08200a8

Please sign in to comment.