E re o na le sete ya diaekhone ka go Figma le projeke ka go React/Vue/eng kapa eng ye nngwe. Ga go makatše ge o tla swanelwa ke go diriša diaekhone tšeo. Re ka di reka ka ntle bjang?
Ge e ba o le manganga ka mo go lekanego, o ka di taonelouta ka e tee ka e tee gomme wa di oketša e le dithoto. Eupša yeo ke tsela e nyamišago. Ga go na likey.
A re tlogeleng go nyama gomme re be ba šiišago go e na le moo. Se ke seo re tlago go se hloka:
*ga go na lešata le lengwe leo le filwego*
Re tla hloka letshwao la Figma. Ga ke nagane gore go a nyakega go hlaloša ka moo o ka dirago se, ka fao karolo ya thušo ke ye go e na le moo: https://help.figma.com/hc/en-us/articles/8085703771159-Manage-personal-access-tokens .
Dipeakanyo tša go se fetoge di botse ka mo go lekanego: re hloka phihlelelo ya go bala fela go dikagare tša faele.
Ke tla šomiša Diaekhone tša Moralo wa Didirišwa (Setšhaba) bjalo ka mohlala.
Re tla hloka senotlolo sa faele le id ya node e ka sehloohong:
Bjale ka ge re na le dinyakwa tša pele tše di lekanego, a re thomeng go ngwala dikhoutu. Ke rata dingwalwa tša ka tšeo di arotšwego go tšwa go khoutu ya projeke ye kgolo, ka fao ke tla hlama foltara ya scripts
ka modung le fetch-icons.ts
ka go yona. Ga go nyakege gore o e dire ka go TypeScript, eupša e dira gore sehlogo se se be bjalo ka sa go makatša, ka fao ke tla sepela le sona.
Le ge go le bjalo, se se tla nyaka banyalani ba bangwe ba go ithekga:
yarn add -D tsx dotenv axios @figma/rest-api-spec
dotenv
e mo go diriša diphetogo tša .env
, tsx
— go sepetša sengwalwa sa TS (fancy, gopola?), @figma/rest-api-spec
ke ya polokego ya mohuta, gomme axios
ke feela ka gobane ke e tlwaetše. E tee feela yeo e nyakegago ke dotenv
(ntle le ge o lokile ka go oketša senotlelo sa API go khoutu), gomme ke tla oketša phetolelo ya “e hlwekilego” mafelelong. Ga bjale, re tla ba le peakanyo ye, gomme se ke seo re thomago ka sona:
import * as dotenv from "dotenv"; dotenv.config(); const PERSONAL_ACCESS_TOKEN = String( process.env.VITE_FIGMA_PERSONAL_ACCESS_TOKEN ); // I've added my Figma token to the .env file, and so should you const FIGMA_API_URL = "https://api.figma.com/v1"; const FILE_KEY = "v50KJO82W9bBJUppE8intT"; // this one is from the URL const NODE_ID = "2402-2207"; // node-id query param, also from the URL
Mathomong, re tla hwetša metadata ya foreime ye kgolo:
import { GetFileNodesResponse, GetImagesResponse, HasChildrenTrait, } from "@figma/rest-api-spec"; // ... const fetchFrameData = async ( nodeId: string ): Promise<HasChildrenTrait> => { const { data } = await axios.get<GetFileNodesResponse>( `${FIGMA_API_URL}/files/${FILE_KEY}/nodes?ids=${nodeId}`, getConfig() ); return data.nodes[nodeId].document as HasChildrenTrait; };
E tla bušetša tshedimošo ka bana ba yona. Tšeo e ka ba diswantšho (mohuta wa tšona e tla ba INSTANCE
) goba diforeime tše dingwe tšeo re tlago go di sekaseka ka go boeletšwa:
const getImageNodes = ( frameData: HasChildrenTrait ): Record<string, string> => { const nodes: Record<string, string> = {}; for (const image of frameData.children.filter( (node) => node.type === 'INSTANCE' )) { // normalizeName simply converts 'check-box' to 'CheckBox' const name = normalizeName(image.name); const id = image.id; nodes[id] = name; } for (const frame of frameData.children.filter( (node) => node.type === 'FRAME' )) { Object.assign(nodes, getImageNodes(frame)); } return nodes; };
Sa mafelelo, ge re na le sehlopha sa di-ID tša seswantšho, re tla lata di-URL tša faele ya SVG:
const fetchImageUrls = async ( nodeIds: string[] ): Promise<GetImagesResponse> => { const { data } = await axios.get<GetImagesResponse>( `${FIGMA_API_URL}/images/${FILE_KEY}?ids=${nodeIds.join(",")}&format=svg`, getConfig() ); return data; };
Gomme re tla feleletša re na le lenaneo la dilo tše bjalo:
{ name: 'CheckBox', url: 'https://figma-alpha-api.s3.us-west-2.amazonaws.com/images/7dd5bc31-4f26-4701-b155-7bf7dea45824' }
Bjalo ka ge o šetše o phopholeditše, re tla di taonelouta ka moka, eupša yeo ga se karolo yeo e kgahlišago kudu.
Nako le nako ge re lata SVG, re hwetša selo sa go swana le seo:
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M17 6H7C3.69 6 1 8.69 [...] 9 17 9Z" fill="black" /> </svg>
Re tla tloša dithegi tša svg
ka ge di swana bakeng sa leswao le lengwe le le lengwe (ke tšea gore di na le bogolo bjo bo swanago bakeng sa go ba bonolo). Eupša seo se kgahlišago kudu ke gore re tla tšeela sebaka ka moka ga fill=”black”
ka seswari sa lefelo ka go thempleite ya kgonthe, gomme ka lebaka leo, re tla ba le mošomo wo bjalo:
export const IconToggleOn = (color: string) => `<path d="M17 6H7C3.69 [...] 9 17 9Z" fill="${color}"/>`;
Kamoo re e hwetšago ka gona ke ye:
const cleanupSvg = (data: string): string => { const svgTags = /<\/?svg.*?>/g; const colorFills = /fill=["'].+?["']/g; return data .replace(svgTags, "") .replace(colorFills, 'fill="${color}"') .replace(/\n/g, ""); };
Go molaleng gore, o ka se hloke go tšeela mebala legato ge e ba o swanetše go tsenya dilogo tše dingwe ka ntle, eupša go di direla tlhaologanyo e fapanego e tla ba mošomo wa gago wa gae.
Go lokile, leano la rena ke le:
Nka se bolele faele ka moka—o ka e hlahloba go GitHub . A re no lebelela go taonelouta ka bogona:
const FILE_BATCH_SIZE = 10; const fileContent: string[] = []; const getPromise = async (item: IconData) => { try { const { data } = await axios.get<string>( item.url, getConfig("image/svg+xml") // returns necessary options and headers ); return { name: item.name, data }; } catch (err) { console.error(err); } }; for (let i = 0; i < iconsData.length; i += FILE_BATCH_SIZE) { const batch = await Promise.allSettled( iconsData.slice(i, i + FILE_BATCH_SIZE).map(getPromise) ); for (const icon of batch) { if (icon?.status === "fulfilled" && icon.value) { const iconName = `Icon${icon.value.name}`; const svgData = cleanupSvg(icon.value.data); fileContent.push( `export const ${iconName} = (color: string) =>\n \`${svgData}\`;\n` ); } } }
Batching e bohlokwa mo ka gobane go sego bjalo, Figma e ka se go rate ge o tšea sephetho sa go taonelouta difaele tše dikete tše mmalwa ka go bapelana.
Ge o hloka go hwetša leswao ka leina leo o le amogelago go tšwa go backend, o ka hlama gape pukuntšu:
const iconArray: string[] = []; // ... for (const icon of batch) { if (icon?.status === "fulfilled" && icon.value) { const iconName = `Icon${icon.value.name}`; const svgData = cleanupSvg(icon.value.data); fileContent.push( `export const ${iconName} = (color: string) =>\n \`${svgData}\`;\n` ); iconArray.push(iconName); // <-- we added this } } // ... when all files are processed fileContent.push( `\r\nexport const iconDictionary: Record<string, (color: string) => string> = {\r\n ${iconArray.join( ",\r\n " )}\r\n};\r\n` );
Mokgwa wo o mpe kudu ka ge sete ka moka e tla okeletšwa go sehlopha le ge o šomiša leswao le tee fela ka pukuntšu, eupša ka dinako tše dingwe, o swanetše go dira selo se sengwe seo se sa kgahlišego. Gape, \r\n
moka le dikgoba di mo go thabiša ESLint ya ka: o ka swanelwa ke go beakanya palo ya tšona.
Mogato wa mafelelo ke wo; a re direng faele e mpsha:
import path from "path"; import { fileURLToPath } from "url"; // ... const PATH_TO_ICONS = "../src/assets/icons"; const currentPath = fileURLToPath(import.meta.url); const currentDirectory = path.dirname(currentPath); const fileName = "index.ts"; const filePath = path.join( path.resolve(currentDirectory, PATH_TO_ICONS), fileName ); // ... fs.writeFileSync(filePath, fileContent.join(""));
Ke kgopolo ye botse go hlopha diaekhone ka morago ga go lata di-URL, tšeo di lego bonolo go swana le se:
iconsData.sort((a, b) => a.name.localeCompare(b.name));
Lenaneo leo le hlophišitšwego le tla ba bonolo go le bala, gomme, seo se lego bohlokwa kudu, re tla ba le phapano ye e balwago neng le neng ge re hwetša diaekhone tše mpsha. Go sego bjalo, taelo ga e kgonthišetšwe, gomme go oketša leswao le tee go ka hlakahlakanya dilo ka moka.
Re hloka karolo yeo e amogelago thapo ya leswao, mmala le bogolo bjalo ka didirišwa tša go thekga le go thala selo se sengwe se se bose:
import React, { useMemo } from "react"; import { IconSvg } from "../types/IconSvg"; interface IconProps { svg: IconSvg; // type IconSvg = (color: string) => string; color?: string; size?: number | string; } const refine = (x: string | number) => { return typeof x === "number" || !/\D+/.test(x) ? `${x}px` : x; }; const MyIcon: React.FC<IconProps> = ({ svg, color, size, }) => { const iconColor = useMemo(() => color ?? "black", [color]); const refinedSize = useMemo(() => refine(size ?? 24), [size]); const currentIcon = useMemo(() => svg(currentColor), [svg, currentColor]); return ( <svg viewBox="0 0 24 24" // make sure it's the same as in Figma dangerouslySetInnerHTML={{ __html: currentIcon }} style={{ width: refinedSize, minWidth: refinedSize, height: refinedSize, minHeight: refinedSize, }} ></svg> ); }; export default MyIcon;
Ke dumela gore e tloga e otlologile, ntle le go hlwekišwa ga bogolo: ge ke e phethagatša ka lekga la mathomo, Chrome e amogetše dinomoro bjalo ka dithoto tša CSS tša bophara/bophagamo, eupša Firefox ga se ya dira bjalo, ka fao ke ile ka tlaleletša ka px
. Le ge e se sa le molato, a re e bolokeng ka fao e swanetšego go ba ka gona go ya ka maemo.
Gomme mo ke autocomplete yeo ke e holofeditšego:
Ke ka fao ke e apeago ka gona. Ke tshepa gore o e hwetša e le mohola.
Bofokodi bja mokgwa wo ke gore diaekhone di tla ba di tsentšwe ka gare gomme tša se bolokwe ka lebaka la seo. Le ge go le bjalo, ga ke nagane gore ke taba ye kgolo bakeng sa di-byte tše sego kae. Go feta moo, o ka oketša ka go dikološa, wa fetoša mmala ge o phaphamala, selo le ge e le sefe se sengwe, gomme o tla ba le thipa e nyenyane ya madira a Switzerland ya diaekhone tšeo.
Gape, e tla nyaka faele ye e rulagantšwego ka go Figma. Eupša hei, ge o ka kgona go ngwala khoutu ye ka moka, o ka hlohleletša gape batšweletši ba gago gore ba e hlophiše.
O ka hwetša khoutu ye e tletšego, go akaretšwa dikarolo tša React le Vue, le phetolelo ya Node.js yeo e nago le ditshepetšo tše mmalwa mo: https://github.com/Smileek/fetch-icons