@dannote/figma-use 0.5.2 → 0.5.3

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.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.5.3] - 2026-01-18
11
+
12
+ ### Added
13
+
14
+ - **`set font-range`** — style text ranges (bold, color, size for specific characters)
15
+ ```bash
16
+ figma-use set font-range <id> --start 0 --end 5 --style Bold --color "#FF0000"
17
+ ```
18
+ - **`node to-component`** — convert frames to components
19
+ ```bash
20
+ figma-use node to-component <id>
21
+ figma-use node to-component "1:2 1:3 1:4" # Multiple
22
+ ```
23
+ - SKILL.md: added SVG import, font-range, grouping and auto-layout examples
24
+
10
25
  ## [0.5.2] - 2026-01-18
11
26
 
12
27
  ### Fixed
package/SKILL.md CHANGED
@@ -36,7 +36,7 @@ figma-use plugin
36
36
 
37
37
  ## JSX Rendering (Fastest Way)
38
38
 
39
- For complex layouts, use `render --stdin` with pure JSX. No imports needed elements are built-in:
39
+ Use `render --stdin` with **pure JSX only**. No variables, no functions, no imports — just JSX tags:
40
40
 
41
41
  ```bash
42
42
  echo '<Frame style={{padding: 24, gap: 16, flexDirection: "column", backgroundColor: "#FFF", borderRadius: 12}}>
@@ -45,14 +45,18 @@ echo '<Frame style={{padding: 24, gap: 16, flexDirection: "column", backgroundCo
45
45
  </Frame>' | figma-use render --stdin
46
46
  ```
47
47
 
48
+ ⚠️ **stdin does NOT support:** `const`, `let`, `function`, `defineComponent`, `defineComponentSet`, ternary operators, or any JavaScript logic. Only literal JSX.
49
+
48
50
  **Elements:** `Frame`, `Rectangle`, `Ellipse`, `Text`, `Line`, `Star`, `Polygon`, `Vector`, `Group`
49
51
 
50
52
  **Style props:** `width`, `height`, `x`, `y`, `padding`, `paddingTop/Right/Bottom/Left`, `gap`, `flexDirection` (row|column), `justifyContent`, `alignItems`, `backgroundColor`, `borderColor`, `borderWidth`, `borderRadius`, `opacity`, `fontSize`, `fontFamily`, `fontWeight`, `color`, `textAlign`
51
53
 
52
54
  ### Buttons Example (3 sizes)
53
55
 
56
+ Since stdin doesn't support variables, write out each variant explicitly:
57
+
54
58
  ```bash
55
- echo '<Frame style={{gap: 16, flexDirection: "row", padding: 24}}>
59
+ echo '<Frame name="Buttons" style={{gap: 16, flexDirection: "row", padding: 24}}>
56
60
  <Frame name="Small" style={{paddingLeft: 12, paddingRight: 12, paddingTop: 6, paddingBottom: 6, backgroundColor: "#3B82F6", borderRadius: 6, flexDirection: "row", justifyContent: "center", alignItems: "center"}}>
57
61
  <Text style={{fontSize: 12, color: "#FFF"}}>Button</Text>
58
62
  </Frame>
@@ -65,9 +69,25 @@ echo '<Frame style={{gap: 16, flexDirection: "row", padding: 24}}>
65
69
  </Frame>' | figma-use render --stdin
66
70
  ```
67
71
 
68
- ### Advanced: Components & Variants
72
+ ### Converting Frames to Components
73
+
74
+ ```bash
75
+ figma-use node to-component <id> # Single frame
76
+ figma-use node to-component "1:2 1:3 1:4" # Multiple frames
77
+ ```
78
+
79
+ ### Grouping and Auto-Layout
80
+
81
+ ```bash
82
+ figma-use group create "1:2 1:3" # Group nodes (auto-converts to frame)
83
+ figma-use set layout <id> --mode HORIZONTAL --gap 8 --padding 16
84
+ ```
85
+
86
+ Note: Groups auto-convert to frames after sync, so `set layout` works immediately.
87
+
88
+ ### Advanced: ComponentSets with Variants (via files)
69
89
 
70
- For `defineComponent`, `defineComponentSet`, `defineVars` use files with imports:
90
+ For proper Figma ComponentSets with variant properties, create a `.figma.tsx` file:
71
91
 
72
92
  ```bash
73
93
  figma-use render --examples # Full API reference
@@ -109,12 +129,20 @@ figma-use set radius <id> 12
109
129
  figma-use set opacity <id> 0.5
110
130
  figma-use set text <id> "New text"
111
131
  figma-use set font <id> --family "Inter" --style "Bold" --size 20
132
+ figma-use set font-range <id> --start 0 --end 5 --style Bold --color "#FF0000"
112
133
  figma-use set layout <id> --mode VERTICAL --gap 12 --padding 16
113
134
  figma-use node move <id> --x 100 --y 200
114
135
  figma-use node resize <id> --width 300 --height 200
115
136
  figma-use node delete <id>
116
137
  ```
117
138
 
139
+ ### Import
140
+
141
+ ```bash
142
+ figma-use import --svg '<svg width="100" height="100"><circle cx="50" cy="50" r="40" fill="red"/></svg>'
143
+ figma-use import --svg "$(cat icon.svg)" --x 100 --y 200
144
+ ```
145
+
118
146
  ### Export
119
147
 
120
148
  ```bash
@@ -129,6 +157,13 @@ figma-use export selection --output selection.png
129
157
  figma-use page list
130
158
  figma-use page set "Page Name"
131
159
  figma-use viewport zoom-to-fit <ids...>
160
+ figma-use viewport get
161
+ figma-use viewport set --x 100 --y 200 --zoom 1.5
162
+ ```
163
+
164
+ **Always zoom after creating elements** — otherwise the user won't see what you made:
165
+ ```bash
166
+ figma-use viewport zoom-to-fit <created-node-id>
132
167
  ```
133
168
 
134
169
  ### Variables & Styles
package/dist/cli/index.js CHANGED
@@ -28886,6 +28886,44 @@ var set_parent_default = defineCommand({
28886
28886
  }
28887
28887
  });
28888
28888
 
28889
+ // packages/cli/src/commands/node/to-component.ts
28890
+ init_format();
28891
+ var to_component_default = defineCommand({
28892
+ meta: { description: "Convert frame(s) to component(s)" },
28893
+ args: {
28894
+ ids: { type: "positional", description: "Node IDs to convert", required: true },
28895
+ json: { type: "boolean", description: "Output as JSON" }
28896
+ },
28897
+ async run({ args }) {
28898
+ try {
28899
+ const ids = args.ids.split(/[\s,]+/).filter(Boolean);
28900
+ const result = await sendCommand("eval", {
28901
+ code: `
28902
+ const ids = ${JSON.stringify(ids)}
28903
+ const result = []
28904
+ for (const id of ids) {
28905
+ const node = await figma.getNodeByIdAsync(id)
28906
+ if (node && 'createComponentFromNode' in figma) {
28907
+ const comp = figma.createComponentFromNode(node)
28908
+ result.push({ id: comp.id, name: comp.name })
28909
+ }
28910
+ }
28911
+ return result
28912
+ `
28913
+ });
28914
+ if (args.json) {
28915
+ console.log(JSON.stringify(result, null, 2));
28916
+ } else {
28917
+ for (const comp of result) {
28918
+ console.log(ok(`Converted to component "${comp.name}" (${comp.id})`));
28919
+ }
28920
+ }
28921
+ } catch (error) {
28922
+ handleError(error, args.json);
28923
+ }
28924
+ }
28925
+ });
28926
+
28889
28927
  // packages/cli/src/commands/node/index.ts
28890
28928
  var node_default = defineCommand({
28891
28929
  meta: { description: "Node operations" },
@@ -28898,7 +28936,8 @@ var node_default = defineCommand({
28898
28936
  rename: rename_default,
28899
28937
  move: move_default,
28900
28938
  resize: resize_default,
28901
- "set-parent": set_parent_default
28939
+ "set-parent": set_parent_default,
28940
+ "to-component": to_component_default
28902
28941
  }
28903
28942
  });
28904
28943
  // packages/cli/src/commands/create/rect.ts
@@ -29565,6 +29604,38 @@ var font_default = defineCommand({
29565
29604
  }
29566
29605
  });
29567
29606
 
29607
+ // packages/cli/src/commands/set/font-range.ts
29608
+ init_output();
29609
+ var font_range_default = defineCommand({
29610
+ meta: { description: "Set font properties for a text range" },
29611
+ args: {
29612
+ id: { type: "positional", description: "Text node ID", required: true },
29613
+ start: { type: "string", required: true, description: "Start index (0-based)" },
29614
+ end: { type: "string", required: true, description: "End index (exclusive)" },
29615
+ family: { type: "string", description: "Font family" },
29616
+ style: { type: "string", description: "Font style (Regular, Bold, Italic, etc)" },
29617
+ size: { type: "string", description: "Font size" },
29618
+ color: { type: "string", description: "Text color (hex)" },
29619
+ json: { type: "boolean", description: "Output as JSON" }
29620
+ },
29621
+ async run({ args }) {
29622
+ try {
29623
+ const result = await sendCommand("set-font-range", {
29624
+ id: args.id,
29625
+ start: parseInt(args.start),
29626
+ end: parseInt(args.end),
29627
+ family: args.family,
29628
+ style: args.style,
29629
+ size: args.size ? parseFloat(args.size) : undefined,
29630
+ color: args.color
29631
+ });
29632
+ printResult(result, args.json);
29633
+ } catch (error) {
29634
+ handleError(error, args.json);
29635
+ }
29636
+ }
29637
+ });
29638
+
29568
29639
  // packages/cli/src/commands/set/effect.ts
29569
29640
  var effect_default = defineCommand({
29570
29641
  meta: { description: "Set effect (shadow, blur)" },
@@ -29781,6 +29852,7 @@ var set_default = defineCommand({
29781
29852
  locked: locked_default,
29782
29853
  text: text_default2,
29783
29854
  font: font_default,
29855
+ "font-range": font_range_default,
29784
29856
  effect: effect_default,
29785
29857
  layout: layout_default,
29786
29858
  constraints: constraints_default,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dannote/figma-use",
3
- "version": "0.5.2",
3
+ "version": "0.5.3",
4
4
  "description": "Control Figma from the command line. Full read/write access for AI agents.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -766,6 +766,26 @@
766
766
  if (fontSize !== void 0) node.fontSize = fontSize;
767
767
  return serializeNode(node);
768
768
  }
769
+ case "set-font-range": {
770
+ const { id, start, end, family, style, size, color } = args;
771
+ const node = yield figma.getNodeByIdAsync(id);
772
+ if (!node || node.type !== "TEXT") throw new Error("Text node not found");
773
+ if (family || style) {
774
+ const currentFont = node.getRangeFontName(start, end);
775
+ const newFamily = family || currentFont.family;
776
+ const newStyle = style || currentFont.style;
777
+ yield loadFont(newFamily, newStyle);
778
+ node.setRangeFontName(start, end, { family: newFamily, style: newStyle });
779
+ }
780
+ if (size !== void 0) {
781
+ node.setRangeFontSize(start, end, size);
782
+ }
783
+ if (color) {
784
+ const rgb = hexToRgb(color);
785
+ node.setRangeFills(start, end, [{ type: "SOLID", color: rgb }]);
786
+ }
787
+ return serializeNode(node);
788
+ }
769
789
  case "get-children": {
770
790
  const { id, depth } = args;
771
791
  const node = yield figma.getNodeByIdAsync(id);