Skip to content

Commit

Permalink
f-button initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
vikas-cldcvr committed Jul 21, 2022
1 parent 24f6d13 commit dda30de
Show file tree
Hide file tree
Showing 17 changed files with 776 additions and 82 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"packages/*"
],
"scripts": {
"storybook": "start-storybook -p 6006",
"storybook": "start-storybook -p 6007",
"start": "yarn storybook",
"build-storybook": "build-storybook",
"prebuild-flow-core": "cd packages/custom-elements-manifest-vue && yarn build",
Expand Down
102 changes: 102 additions & 0 deletions packages/flow-core/figma/api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/* eslint-disable no-undef */
/* eslint-disable @typescript-eslint/no-var-requires */
const api = require("axios");

const headers = {
"X-FIGMA-TOKEN": process.env.FIGMA_TOKEN,
};
/**
* api endpoint for files
*
*/
const instanceFiles = api.create({
baseURL: `https://api.figma.com/v1/files/${process.env.FILE_KEY}`,
headers,
});
/**
* api endpoint for styles
*
*/
const instanceStyles = api.create({
baseURL: `https://api.figma.com/v1/files/${process.env.FILE_KEY}/styles`,
headers,
});
/**
* api endpoint for images
*
*/
const instanceImages = api.create({
baseURL: `https://api.figma.com/v1/images/${process.env.FILE_KEY}`,
headers,
});
/**
* get Figma document info
*
* @return {Promise<Object>}
*/
const getDocument = async () => instanceFiles.get("/");

/**
* get Figma style info
*
* @return {Promise<Object>}
*/
const getStyles = async () => instanceStyles.get("/");
/**
* get Figma node info
*
* @param {string} nodeId
* @return {Promise<Object>}
*/
const getNode = async (nodeId) =>
instanceFiles.get(`/nodes?ids=${decodeURIComponent(nodeId)}`);
/**
* get Figma node children
*
* @param {string} nodeId
* @return {Promise<[Object]>}
*/
const getNodeChildren = async (nodeId) => {
const {
data: { nodes },
} = await instanceFiles.get(`/nodes?ids=${decodeURIComponent(nodeId)}`);
return nodes[nodeId].document.children;
};
/**
* get svg image resource url
*
* @param {string} nodeId
* @return {Promise<string>}
*/
const getSvgImageUrl = async (nodeId) => {
const {
data: { images, err },
} = await instanceImages.get(
`/?ids=${decodeURIComponent(nodeId)}&format=svg`
);
return images[nodeId];
};
/**
* get svg image resource urls
*
* @param {string} nodeId
* @return {Promise<string[]>}
*/
const getAllSvgImageUrl = async (nodeId) => {
const {
data: { images, err },
} = await instanceImages.get(
`/?ids=${decodeURIComponent(nodeId)}&format=svg`
);
return images;
};
const getIconContent = async (url) => api.get(url);
module.exports = {
getDocument,
getNode,
getNodeChildren,
getSvgImageUrl,
getIconContent,
getAllSvgImageUrl,
getStyles,
};
116 changes: 116 additions & 0 deletions packages/flow-core/figma/downloadIcons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/* eslint-disable no-undef */
/* eslint-disable @typescript-eslint/no-var-requires */

const { getDocument, getAllSvgImageUrl, getIconContent } = require("./api");
const fs = require("fs");

function sliceIntoChunks(arr, chunkSize) {
const res = [];
for (let i = 0; i < arr.length; i += chunkSize) {
const chunk = arr.slice(i, i + chunkSize);
res.push(chunk);
}
return res;
}
/**
* Get document of specified file Id
*/
getDocument()
.then((response) => {
const componetKeys = Object.keys(response.data.components);
const ids = componetKeys.join(",");

/**
* Components count
*/
process.stdout.write(`${componetKeys.length} Icons present in Figma! \n`);

/**
* Storing id to name mapping
*/
const iconNameMapping = {};
for (const [id, component] of Object.entries(
Object.entries(response.data.components)
)) {
iconNameMapping[id] = component[1].name;
}
/**
* async/await removed to download asynchronously
*/
getAllSvgImageUrl(ids)
.then(
async (urls) => {
process.stdout.write(
`\x1b[36m \rDownloading ${componetKeys.length} icons.`
);

const iconUrls = [];
for (const [id, url] of Object.entries(Object.entries(urls))) {
/**
* Downloading component whose name starts with 'i-'
*/
if (
iconNameMapping[id].startsWith("i-") ||
iconNameMapping[id].startsWith("p-")
) {
iconUrls.push({ id, url });
}
}
const batchSize = 10;
const batches = sliceIntoChunks(iconUrls, batchSize);

for (let i = 0; i < batches.length; i++) {
const promises = [];
process.stdout.write(
`\x1b[36m \rDownloading ${i * batchSize} to ${
i * batchSize + batchSize
} ...`
);

batches[i].forEach(({ id, url }) => {
/**
* Downloading component whose name starts with 'i-'
*/
if (
iconNameMapping[id].startsWith("i-") ||
iconNameMapping[id].startsWith("p-")
) {
promises.push(
getIconContent(url[1]).then(
(icon) => {
/**
* Writing file in svg folder
*/
fs.writeFileSync(
`${__dirname}/../lib/Icon/svg/${iconNameMapping[id]}.svg`,
icon.data
);
},
(error) => {
console.log(
`Failed to load svg ${iconNameMapping[id]} - ${url[1]}`,
error.code
);
}
)
);
}
});
await Promise.all(promises);
}
process.stdout.clearLine();
process.stdout.write(
`\x1b[36m \r${componetKeys.length} Icons downloaded! \n \n `
);
},
(error) => {
console.error(error);
}
)
.catch((error) => {
console.error(error);
});
})
.catch((error) => {
console.error(error);
});
89 changes: 89 additions & 0 deletions packages/flow-core/figma/syncColors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/* eslint-disable no-undef */
/* eslint-disable @typescript-eslint/no-var-requires */

const { getStyles, getNode } = require("./api");
const prettier = require("prettier");

const fs = require("fs");

const rgbToHex = (r, g, b) =>
"#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);

function generateTokenScss(colorTokens) {
const tokenFileName = `${__dirname}/../src/shared/_tokens.scss`;

// let scss = `@layer default,custom;
// @layer default { `;
let scss = `
@function getHover($value) {
$hover-color: lighten($value, 10%);
@if lightness($value) > 50 {
$hover-color: darken($value, 10%);
}
@return $hover-color;
}
`;
for (const [theme, tokens] of Object.entries(colorTokens)) {
const tokenEntries = Object.entries(tokens);

scss += `
[flow-element][theme="${theme}"]{ `;

for (let [variable, value] of tokenEntries) {
variable = `color-${variable}`;
scss += `$${variable} : ${value} ;\n`;
scss += `--${variable} : #{$${variable}} ;\n`;
scss += `--${variable}-hover : #{getHover($${variable})};\n`;
}
scss += `
};\n`;
}
// scss += `}`;
try {
fs.writeFileSync(
tokenFileName,
prettier.format(scss, {
printWidth: 100,
singleQuote: true,
tabWidth: 4,
parser: "css",
})
);
console.log(`\x1b[32m \r ${tokenFileName} generated \u2705 \x1b[0m`);
} catch (e) {
console.log(e);
}
}
/**
* Get document of specified file Id
*/
getStyles()
.then(async (response) => {
let nodeids = [];
response.data.meta.styles.forEach((element) => {
nodeids.push(element.node_id);
});
getNode(nodeids.join(",")).then(async (response) => {
const colorTokens = {};
// eslint-disable-next-line @typescript-eslint/no-unused-vars
for (const [_id, obj] of Object.entries(response.data.nodes)) {
const { r, g, b } = obj.document.fills[0].color;

const [theme, token] = obj.document.name.split("/");
if (!colorTokens[theme]) {
colorTokens[theme] = {};
}

colorTokens[theme][token] = rgbToHex(
+(r * 255).toFixed(0),
+(g * 255).toFixed(0),
+(b * 255).toFixed(0)
);
}
generateTokenScss(colorTokens);
});
console.log("\n");
})
.catch((error) => {
console.error(error);
});
2 changes: 2 additions & 0 deletions packages/flow-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"compile": "./compile.sh",
"build": "vite build --emptyOutDir && tsc -emitDeclarationOnly",
"build:watch": "tsc --watch",
"sync-colors": "FIGMA_TOKEN=206330-1bbeb796-39d3-408e-ab7a-b6c8551111a5 FILE_KEY=v59oSoU65b7yfW0hGfYqUj node ./figma/syncColors.js",
"lint:eslint": "eslint 'src/**/*.ts' './custom-elements.vue.ts'",
"analyze": "cem analyze --litelement --globs \"src/**/*.ts\" && wca analyze src --format vscode --outFile html.html-data.json",
"analyze:watch": "cem analyze --litelement --globs \"src/**/*.ts\" --watch",
Expand All @@ -36,6 +37,7 @@
"@web/dev-server-esbuild": "^0.3.0",
"@web/dev-server-rollup": "0.3.18",
"@web/test-runner": "^0.13.30",
"axios": "^0.27.2",
"esbuild-sass-plugin": "2.2.6",
"eslint": "^8.17.0",
"lit-html": "^2.2.5",
Expand Down
56 changes: 56 additions & 0 deletions packages/flow-core/src/components/f-button/f-button.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
@use "sass:map";
@use "sass:math";

$states: (
"primary": var(--color-primary-default),
"subtle": var(--color-success-default),
"success": var(--color-success-default),
"warning": var(--color-warning-default),
"danger": var(--color-danger-default),
);

$states-hover-colors: (
"primary": var(--color-primary-default-hover),
"subtle": var(--color-success-default-hover),
"success": var(--color-success-default-hover),
"warning": var(--color-warning-default-hover),
"danger": var(--color-danger-default-hover),
);

$sizes: (
"x-small": 20px,
"small": 28px,
"medium": 36px,
"large": 44px,
);
f-button {
cursor: pointer;
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0px 20px;
font-weight: 600;
text-transform: uppercase;
font-size: 14px;
color: var(--color-surface-default);

@each $state, $color in $states {
&[state="#{$state}"][variant="fill"] {
background-color: $color;

&:hover {
background-color: map.get($states-hover-colors, $state);
}
}
}

@each $size, $value in $sizes {
&[size="#{$size}"] {
height: $value;

&[shape="round"] {
border-radius: math.div($value, 2);
}
}
}
}

0 comments on commit dda30de

Please sign in to comment.