Skip to content
This repository has been archived by the owner on Aug 14, 2022. It is now read-only.

Commit

Permalink
Add support for array values to components
Browse files Browse the repository at this point in the history
Co-authored-by: Josh Star <joshstar@mail.com>
  • Loading branch information
Matan Kushner and joshstar committed Aug 7, 2019
1 parent 1f7b3ac commit 582c28d
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 17 deletions.
10 changes: 5 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -10,9 +10,10 @@
"license": "ISC",
"dependencies": {
"css-loader": "^3.1.0",
"dash-get": "^1.0.2",
"html-webpack-inline-source-plugin": "0.0.10",
"html-webpack-plugin": "^3.2.0",
"lodash": "^4.17.15",
"lodash-es": "^4.17.15",
"style-loader": "^0.23.1",
"ts-loader": "^6.0.4",
"typescript": "^3.5.3",
Expand Down
64 changes: 54 additions & 10 deletions src/code.ts
@@ -1,27 +1,71 @@
import get from "dash-get";
figma.showUI(__html__);

figma.ui.onmessage = async msg => {
if (msg.type === "populate") {
const textNodes = figma.currentPage.findAll(
node => node.type === "TEXT"
) as TextNode[];
if (textNodes.length == 0) return;
const instanceNodes = figma.currentPage.findAll(
node => node.type === "INSTANCE"
) as InstanceNode[];

textNodes.map(node => replacePlaceholder(node, msg.body));
// Keep a count of the number of instances per component
type componentIndexMap = Map<ComponentNode, number>;
const componentIndices: componentIndexMap = new Map();

instanceNodes.forEach(instanceNode => {
// Replace the empty `[]` in all instance nodes with incrementing indices
const currentVal = componentIndices.get(instanceNode.masterComponent) || 0;
const textNodes = findTextNodes(instanceNode);
textNodes.forEach(textNode => replacePlaceholder(textNode, msg.body, currentVal));

// Increment number in map
componentIndices.set(instanceNode.masterComponent, currentVal + 1);
});

// const textNodes = figma.currentPage.findAll(
// node => node.type === "TEXT"
// ) as TextNode[];
// if (textNodes.length == 0) return;

// textNodes.map(node => replacePlaceholder(node, msg.body));
}
};

// Replace placeholder text values preceeded with a `$` with the value at the
// equivalent json path
async function replacePlaceholder(node: TextNode, json: Object): Promise<null> {
function findTextNodes(rootNode: ChildrenMixin) {
return rootNode.findAll(
node => node.type === "TEXT"
) as TextNode[];
}

/**
* Replace placeholder text values preceeded with a `$` with the value at the
* associated json path. Replace square-brackets with incrementing indices
*/
async function replacePlaceholder(node: TextNode, json: Object, index: number = 0): Promise<null> {
if (!node.characters.startsWith("$")) return;
// Remove "$" from start
const path = node.characters.slice(1);
let path = node.characters.slice(1);
// Populate empty square-brackets with the provided index
path = path.replace("[]", `[${index}]`);

const objValue = get(json, path);
if (objValue == null) return;

await figma.loadFontAsync(node.fontName as FontName);
node.characters = String(objValue);
}

/**
* Equivalent to _.get from lodash
*/
function get(obj, path, def = null) {
var fullPath = path
.replace(/\[/g, '.')
.replace(/]/g, '')
.split('.')
.filter(Boolean);

return fullPath.every(everyFunc) ? obj : def;

function everyFunc(step) {
return !(step && (obj = obj[step]) === undefined);
}
}
2 changes: 1 addition & 1 deletion src/ui.html
Expand Up @@ -3,7 +3,7 @@
<form>
<input
type="text"
value="https://jsonplaceholder.typicode.com/users/3"
value="https://jsonplaceholder.typicode.com/users"
id="url"
/>
</form>
Expand Down

0 comments on commit 582c28d

Please sign in to comment.