Install
npx skillscat add shaul1991/shaul-agents-plugin/skills-design-figma Install via the SkillsCat registry.
SKILL.md
Design Figma Agent
Figma Plugin API ì½ë를 ìì±íì¬ Scripter íë¬ê·¸ì¸ìì ì¤íí ì ìëë¡ ì§ìí©ëë¤.
ìí
- UI ì»´í¬ëí¸ë¥¼ Figma Plugin API ì½ëë¡ ë³í
- Figma ìºë²ì¤ì ëìì¸ ìì ìë ìì±
- ëìì¸ ìì¤í ì»´í¬ëí¸ ì½ë ìì±
í¸ë¦¬ê±° í¤ìë
- figma, í¼ê·¸ë§, scripter, ì¤í¬ë¦½í°
- UI ìì±, ì»´í¬ëí¸ ìì±, ëìì¸ ìì±
ìí¬íë¡ì°
- ì¬ì©ì ìì² ë¶ì (UI ì»´í¬ëí¸, ë ì´ìì, ì¤íì¼ ë±)
- Figma Plugin API ì½ë ìì±
- Scripter íë¬ê·¸ì¸ìì ì¤í ê°ë¥í ííë¡ ì¶ë ¥
- ì¬ì©ìê° Figma Scripterì ë¶ì¬ë£ê¸° í ì¤í
Figma Plugin API 기본 ì§ì
ëí ìì±
// Rectangle
const rect = figma.createRectangle()
rect.resize(width, height)
rect.x = x
rect.y = y
rect.fills = [{ type: 'SOLID', color: { r: 0, g: 0, b: 0 } }]
rect.cornerRadius = 8
// Ellipse
const ellipse = figma.createEllipse()
ellipse.resize(100, 100)
// Line
const line = figma.createLine()
line.resize(200, 0)
line.strokes = [{ type: 'SOLID', color: { r: 0, g: 0, b: 0 } }]í ì¤í¸ ìì±
const text = figma.createText()
await figma.loadFontAsync({ family: "Inter", style: "Regular" })
text.characters = "Hello World"
text.fontSize = 16
text.fills = [{ type: 'SOLID', color: { r: 0, g: 0, b: 0 } }]Frame ìì±
const frame = figma.createFrame()
frame.resize(400, 300)
frame.name = "Card Component"
frame.fills = [{ type: 'SOLID', color: { r: 1, g: 1, b: 1 } }]
frame.cornerRadius = 12
// Auto Layout ì¤ì
frame.layoutMode = "VERTICAL"
frame.primaryAxisAlignItems = "CENTER"
frame.counterAxisAlignItems = "CENTER"
frame.itemSpacing = 16
frame.paddingTop = 24
frame.paddingBottom = 24
frame.paddingLeft = 24
frame.paddingRight = 24ì»´í¬ëí¸ ìì±
const component = figma.createComponent()
component.resize(200, 48)
component.name = "Button"그룹í
const group = figma.group([rect, text], figma.currentPage)
group.name = "My Group"ìì ë³í ì í¸ë¦¬í°
// HEX to RGB (0-1 ë²ì)
function hexToRgb(hex: string) {
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
return result ? {
r: parseInt(result[1], 16) / 255,
g: parseInt(result[2], 16) / 255,
b: parseInt(result[3], 16) / 255
} : { r: 0, g: 0, b: 0 }
}그림ì í¨ê³¼
node.effects = [{
type: 'DROP_SHADOW',
color: { r: 0, g: 0, b: 0, a: 0.15 },
offset: { x: 0, y: 4 },
radius: 8,
spread: 0,
visible: true,
blendMode: 'NORMAL'
}]ì¤í¸ë¡í¬ (í ë리)
node.strokes = [{ type: 'SOLID', color: { r: 0.9, g: 0.9, b: 0.9 } }]
node.strokeWeight = 1ë·°í¬í¸ ì´ë
figma.viewport.scrollAndZoomIntoView([node])
figma.currentPage.selection = [node]ì½ë ì¶ë ¥ íì
Scripter íë¬ê·¸ì¸ìì ë°ë¡ ì¤íí ì ìëë¡ ë¤ì íìì¼ë¡ ì¶ë ¥:
// [ì»´í¬ëí¸ ì´ë¦] - Scripterìì ì¤í
// ìì± ìì¹: íì¬ ì í ìì¹ ëë (0, 0)
// === ì½ë ìì ===
// í°í¸ ë¡ë (í
ì¤í¸ ì¬ì© ì íì)
await figma.loadFontAsync({ family: "Inter", style: "Regular" })
// ë©ì¸ ì½ë
const frame = figma.createFrame()
// ... ì½ë ...
// ë·°í¬í¸ ì´ë ë° ì í
figma.currentPage.selection = [frame]
figma.viewport.scrollAndZoomIntoView([frame])
// === ì½ë ë ===주ìì¬í
- í°í¸ ë¡ë íì: í
ì¤í¸ ì¬ì© ì ë°ëì
figma.loadFontAsync()í¸ì¶ - ìì ë²ì: RGB ê°ì 0-1 ë²ì (255ë¡ ëë기)
- ì¢íê³: ì¼ìª½ ìë¨ì´ (0, 0), ì¤ë¥¸ìª½/ìëë¡ ê°ìë¡ ì¦ê°
- appendChild: Frameì ìì ìì ì¶ê° ì ì¬ì©
- ë¹ë기 ì²ë¦¬: í°í¸ ë¡ë ë± ë¹ë기 ìì ì await ì¬ì©