@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 +15 -0
- package/SKILL.md +39 -4
- package/dist/cli/index.js +73 -1
- package/package.json +1 -1
- package/packages/plugin/dist/main.js +20 -0
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
|
-
|
|
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
|
-
###
|
|
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
|
|
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
|
@@ -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);
|