@biolab/talk-to-figma 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -157,6 +157,12 @@ async function handleCommand(command, params) {
157
157
  return await setCornerRadius(params);
158
158
  case "set_text_content":
159
159
  return await setTextContent(params);
160
+ case "set_font_family":
161
+ return await setFontFamily(params);
162
+ case "set_font_size":
163
+ return await setFontSize(params);
164
+ case "set_font_weight":
165
+ return await setFontWeight(params);
160
166
  case "clone_node":
161
167
  return await cloneNode(params);
162
168
  case "scan_text_nodes":
@@ -1466,7 +1472,36 @@ async function setVariableBinding(params) {
1466
1472
  if (!variable) {
1467
1473
  throw new Error(`Variable not found: ${variableId}`);
1468
1474
  }
1469
- node.setBoundVariable(field, variable);
1475
+
1476
+ // Handle paint color bindings (fills/N/color, strokes/N/color)
1477
+ const paintMatch = field.match(/^(fills|strokes)\/(\d+)\/color$/);
1478
+ if (paintMatch) {
1479
+ const [, paintType, indexStr] = paintMatch;
1480
+ const index = parseInt(indexStr, 10);
1481
+ const paints = node[paintType];
1482
+
1483
+ if (!paints || !Array.isArray(paints) || index >= paints.length) {
1484
+ // Create a default solid paint if none exists at the index
1485
+ const alias = figma.variables.createVariableAlias(variable);
1486
+ const newPaint = figma.util.solidPaint({ r: 0, g: 0, b: 0 }, 1);
1487
+ newPaint.boundVariables = { color: alias };
1488
+ if (paintType === "fills") {
1489
+ node.fills = [newPaint];
1490
+ } else {
1491
+ node.strokes = [newPaint];
1492
+ }
1493
+ } else {
1494
+ const alias = figma.variables.createVariableAlias(variable);
1495
+ const paintsCopy = paints.slice();
1496
+ const paint = Object.assign({}, paintsCopy[index]);
1497
+ paint.boundVariables = Object.assign({}, paint.boundVariables, { color: alias });
1498
+ paintsCopy[index] = paint;
1499
+ node[paintType] = paintsCopy;
1500
+ }
1501
+ } else {
1502
+ node.setBoundVariable(field, variable);
1503
+ }
1504
+
1470
1505
  return {
1471
1506
  success: true,
1472
1507
  nodeId: node.id,
@@ -1809,6 +1844,88 @@ async function setTextContent(params) {
1809
1844
  }
1810
1845
  }
1811
1846
 
1847
+ function mapFontWeight(weight) {
1848
+ switch (weight) {
1849
+ case 100: return "Thin";
1850
+ case 200: return "Extra Light";
1851
+ case 300: return "Light";
1852
+ case 400: return "Regular";
1853
+ case 500: return "Medium";
1854
+ case 600: return "Semi Bold";
1855
+ case 700: return "Bold";
1856
+ case 800: return "Extra Bold";
1857
+ case 900: return "Black";
1858
+ default: return "Regular";
1859
+ }
1860
+ }
1861
+
1862
+ async function setFontFamily(params) {
1863
+ const { nodeId, fontFamily, fontStyle = "Regular" } = params || {};
1864
+
1865
+ if (!nodeId) throw new Error("Missing nodeId parameter");
1866
+ if (!fontFamily) throw new Error("Missing fontFamily parameter");
1867
+
1868
+ const node = await figma.getNodeByIdAsync(nodeId);
1869
+ if (!node) throw new Error(`Node not found with ID: ${nodeId}`);
1870
+ if (node.type !== "TEXT") throw new Error(`Node is not a text node: ${nodeId}`);
1871
+
1872
+ try {
1873
+ const newFont = { family: fontFamily, style: fontStyle };
1874
+ await figma.loadFontAsync(newFont);
1875
+ node.fontName = newFont;
1876
+ return { id: node.id, name: node.name, fontName: node.fontName };
1877
+ } catch (error) {
1878
+ throw new Error(`Error setting font family: ${error.message}`);
1879
+ }
1880
+ }
1881
+
1882
+ async function setFontSize(params) {
1883
+ const { nodeId, fontSize } = params || {};
1884
+
1885
+ if (!nodeId) throw new Error("Missing nodeId parameter");
1886
+ if (fontSize === undefined) throw new Error("Missing fontSize parameter");
1887
+
1888
+ const node = await figma.getNodeByIdAsync(nodeId);
1889
+ if (!node) throw new Error(`Node not found with ID: ${nodeId}`);
1890
+ if (node.type !== "TEXT") throw new Error(`Node is not a text node: ${nodeId}`);
1891
+
1892
+ try {
1893
+ // Load current font before modifying
1894
+ const currentFont = node.fontName === figma.mixed
1895
+ ? node.getRangeFontName(0, 1)
1896
+ : node.fontName;
1897
+ await figma.loadFontAsync(currentFont);
1898
+ node.fontSize = parseInt(fontSize);
1899
+ return { id: node.id, name: node.name, fontSize: node.fontSize };
1900
+ } catch (error) {
1901
+ throw new Error(`Error setting font size: ${error.message}`);
1902
+ }
1903
+ }
1904
+
1905
+ async function setFontWeight(params) {
1906
+ const { nodeId, fontWeight } = params || {};
1907
+
1908
+ if (!nodeId) throw new Error("Missing nodeId parameter");
1909
+ if (fontWeight === undefined) throw new Error("Missing fontWeight parameter");
1910
+
1911
+ const node = await figma.getNodeByIdAsync(nodeId);
1912
+ if (!node) throw new Error(`Node not found with ID: ${nodeId}`);
1913
+ if (node.type !== "TEXT") throw new Error(`Node is not a text node: ${nodeId}`);
1914
+
1915
+ try {
1916
+ const currentFont = node.fontName === figma.mixed
1917
+ ? node.getRangeFontName(0, 1)
1918
+ : node.fontName;
1919
+ const newStyle = mapFontWeight(fontWeight);
1920
+ const newFont = { family: currentFont.family, style: newStyle };
1921
+ await figma.loadFontAsync(newFont);
1922
+ node.fontName = newFont;
1923
+ return { id: node.id, name: node.name, fontName: node.fontName };
1924
+ } catch (error) {
1925
+ throw new Error(`Error setting font weight: ${error.message}`);
1926
+ }
1927
+ }
1928
+
1812
1929
  // Initialize settings on load
1813
1930
  (async function initializePlugin() {
1814
1931
  try {
Binary file