-
Notifications
You must be signed in to change notification settings - Fork 74
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
figma-bot
committed
Jun 19, 2024
1 parent
3388b6c
commit 622b705
Showing
47 changed files
with
937 additions
and
496 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,77 +1,59 @@ | ||
# Code Connect for icons | ||
|
||
`import-icons.ts` is a node script that uses the [Figma API](https://www.figma.com/developers/api) to pull icons from a Figma file and generate a Code Connect file for your icons. This template is meant to be used as a starting point - some parts will need to be edited to work with your design system and code base. These areas are marked with "EDIT THIS" in the file. | ||
This folder includes example scripts for generating Code Connect files for your components. This is useful for icons, where you might have tons of icons that you don't want to manually connect one by one. | ||
|
||
## Usage | ||
|
||
Run the script with e.g `npx tsx`: | ||
To run the scripts, you'll need to set the `FIGMA_ACCESS_TOKEN` env variable. [See here](https://www.figma.com/developers/api#access-tokens) for how to get this token. | ||
|
||
Run the scripts with e.g `npx tsx`: | ||
``` | ||
FIGMA_ACCESS_TOKEN=<my token> npx tsx import-icons.ts | ||
``` | ||
|
||
## Modifying the script | ||
|
||
There are many ways your icons can be setup in Figma and in code. This base template assumes that: | ||
* Your icons in Figma include the string "icon" in the name | ||
* Your icon components in code are named similarly and include the size, e.g `Icon32Search` | ||
|
||
Here are some examples of how you can modify the script to work with your setup. | ||
|
||
### Icons with size as a prop | ||
|
||
If your icons in Figma has properties/variants for size, you can modify the script to handle this. | ||
|
||
Change the `generateCodeConnectIcons` function: | ||
or, if you have the access token in an `.env` file, Code Connect will pick that up: | ||
``` | ||
npx tsx import-icons.ts | ||
``` | ||
|
||
```ts | ||
// ... | ||
## Code Connect Client | ||
|
||
let name = figmaName | ||
.split(/[.-]/g) | ||
.map((part) => part.charAt(0).toUpperCase() + part.slice(1)) | ||
.join('') | ||
`client` includes helper functions for interacting with Figma files and generating Code Connect files. It uses the [Figma REST API](https://www.figma.com/developers/api) under the hood. This folder includes a few example scripts that can be modified to fit your needs. | ||
|
||
// added line: remove the size from the component name | ||
name = name.replace(/[0-9]+/g, '') | ||
`getComponents` will fetch any components in a file, or if a node-id query parameter is provided, any nodes within that frame. The result can then be used to dynamically connect components with `figma.connect()` and write this to a file that can be published with `figma connect publish`. | ||
|
||
// added line: extract the size from the figma name. | ||
// default to 16 if no size specified in the Figma name | ||
const [_match, size] = figmaName.match(/([0-9]+)/) ?? [null, '16'] | ||
``` | ||
import { client } from '@figma/code-connect' | ||
const info: IconInfo = { | ||
id, | ||
name, | ||
figmaName, | ||
figmaUrl, | ||
size, | ||
async function getIcons() { | ||
const components = await client.getComponents('https://figma.com/file/ABc123IjkLmnOPq?node-id=41-41') | ||
const icons = components.filter(({ name }) => name.startsWith('icon')) | ||
// ... write code connect file | ||
} | ||
icons.push(info) | ||
|
||
// ... | ||
``` | ||
|
||
Change the `writeCodeConnectFile` function to include an `example` that passes the size to your icon component: | ||
`getComponents` returns an array of `Component` objects with the following type: | ||
|
||
```ts | ||
async function writeCodeConnectFile(dir: string, icons: IconInfo[]) { | ||
const uniqueNames = new Set([...icons.map((icon) => icon.name)]) | ||
fs.writeFileSync( | ||
path.join(dir, ICONS_CODE_CONNECT_FILE), | ||
`\ | ||
import figma from '@figma/code-connect' | ||
import { | ||
${Array.from(uniqueNames) | ||
.map((iconName) => ` ${iconName},`) | ||
.join('\n')} | ||
} from '${ICONS_IMPORT_PATH}' | ||
${icons | ||
.map( | ||
(icon) => `figma.connect(${icon.name}, '${icon.figmaUrl}', { | ||
example: () => <${icon.name} size={${icon.size}} />, | ||
})`, | ||
) | ||
.join('\n')} | ||
`, | ||
) | ||
``` | ||
interface Component { | ||
// the type of component (only COMPONENT_SET nodes can have variant properties) | ||
type: 'COMPONENT' | 'COMPONENT_SET' | ||
// the name of the component in Figma | ||
name: string | ||
// a unique ID for this node | ||
id: string | ||
// file key for the file containing this node | ||
fileKey: string | ||
// URL to this node | ||
figmaUrl: string | ||
// Properties for this component, keyed by the name of the property | ||
componentPropertyDefinitions: Record<string, { | ||
defaultValue: boolean | string | ||
type: 'BOOLEAN' | 'INSTANCE_SWAP' | 'TEXT' | 'VARIANT' | ||
// All possible values for this property. Only exists on VARIANT properties | ||
variantOptions?: string[] | ||
}> | ||
} | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// change to: "import { client } from '@figma/code-connect'" | ||
import { client } from '../src' | ||
import fs from 'fs' | ||
import path from 'path' | ||
|
||
async function generateIconsWithSizeProp() { | ||
// fetch components from a figma file. If the `node-id` query parameter is used, | ||
// only components within those frames will be included. This is useful if your | ||
// file is very large, as this will speed up the query by a lot | ||
let components = await client.getComponents( | ||
'https://figma.com/file/ABc123IjkLmnOPq?node-id=41-41', | ||
) | ||
|
||
// Map from figma to React component names | ||
components = components.map((component) => ({ | ||
...component, | ||
name: component.name | ||
.split(/[.-]/g) | ||
.map((part) => part.charAt(0).toUpperCase() + part.slice(1)) | ||
.join(''), | ||
})) | ||
|
||
const uniqueNames = new Set([...components.map((c) => c.name)]) | ||
|
||
const file = 'src/components/icons.figma.tsx' | ||
fs.mkdirSync(path.dirname(file), { recursive: true }) | ||
fs.writeFileSync( | ||
file, | ||
`\ | ||
import figma from '@figma/code-connect' | ||
import { | ||
${Array.from(uniqueNames) | ||
.map((iconName) => ` ${iconName},`) | ||
.join('\n')} | ||
} from './Icons' | ||
const props = { | ||
size: figma.enum('Size', { | ||
"12": 12, | ||
"16": 16, | ||
"24": 24, | ||
}) | ||
} | ||
${components | ||
.map( | ||
(c) => `figma.connect(${c.name}, '${c.figmaUrl}', { | ||
props, | ||
example: ({ size }) => <${c.name} size={size} /> | ||
})`, | ||
) | ||
.join('\n')} | ||
`, | ||
) | ||
} | ||
|
||
generateIconsWithSizeProp() |
Oops, something went wrong.