@sangheepark/figma-ds-mcp 0.2.12 → 0.2.14

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.
@@ -298,6 +298,23 @@ function enrichSpec(traversal, mapping) {
298
298
  node.layout['clip-content'] = true;
299
299
  delete node.layout['overflow'];
300
300
  }
301
+ // 6-G: absolute CSS constraints → Figma sizing
302
+ // CSS left:0+right:0 = "stretch to parent width" → width:fill
303
+ // CSS top:0+bottom:0 = "stretch to parent height" → height:fill
304
+ // 6-A 필터링 전에 실행해야 CSS 좌표 정보를 활용 가능
305
+ if (node.layout) {
306
+ const lay = node.layout;
307
+ if (lay['positioning'] === 'absolute' || lay['positioning'] === 'fixed') {
308
+ const l = String(lay['left'] || ''), r = String(lay['right'] || '');
309
+ const t = String(lay['top'] || ''), b = String(lay['bottom'] || '');
310
+ if ((l === '0' || l === '0px') && (r === '0' || r === '0px') && !lay['width']) {
311
+ lay['width'] = 'fill';
312
+ }
313
+ if ((t === '0' || t === '0px') && (b === '0' || b === '0px') && !lay['height']) {
314
+ lay['height'] = 'fill';
315
+ }
316
+ }
317
+ }
301
318
  // 6-A: CSS-only 속성 필터링 (Figma가 지원하지 않는 CSS 속성 제거)
302
319
  if (node.style) {
303
320
  for (const key of Object.keys(node.style)) {
@@ -390,6 +407,42 @@ function enrichSpec(traversal, mapping) {
390
407
  }
391
408
  }
392
409
  }
410
+ // 6-F: sticky-like absolute → normal flow 복원
411
+ // CSS position:sticky → traversal이 positioning:absolute로 변환하는 경우가 있음
412
+ // 정적 화면에서 sticky = normal flow. name 패턴으로 감지하여 복원.
413
+ // 조건: absolute + name이 header/sticky/nav/toolbar 패턴 + 원점 위치 (x:0/없음, y:0/없음)
414
+ if (node.layout?.positioning === 'absolute' && node.name) {
415
+ const isHeaderLike = /header|sticky|nav|toolbar/i.test(node.name);
416
+ const atOrigin = (!node.layout.x || node.layout.x === '0')
417
+ && (!node.layout.y || node.layout.y === '0');
418
+ if (isHeaderLike && atOrigin) {
419
+ delete node.layout['positioning'];
420
+ delete node.layout['x'];
421
+ delete node.layout['y'];
422
+ }
423
+ }
424
+ // 6-H: column parent centering inference (mx-auto 패턴)
425
+ // 웹에서 max-width + mx-auto는 가장 흔한 중앙 정렬 패턴.
426
+ // traversal이 mx-auto를 놓쳤을 때, 구조 패턴으로 추론:
427
+ // column + fill width 부모 + 고정폭 children (같은 width, ≥400px) → align-items:center
428
+ if (node.layout?.direction === 'column'
429
+ && node.layout.width === 'fill'
430
+ && node.children && node.children.length > 0
431
+ && !node.layout['align-items']) {
432
+ const fixedWidths = [];
433
+ for (const child of node.children) {
434
+ const cw = child.layout?.width;
435
+ if (typeof cw === 'string' && /^\d+/.test(cw) && cw !== 'fill') {
436
+ fixedWidths.push(parseInt(cw, 10));
437
+ }
438
+ }
439
+ if (fixedWidths.length > 0) {
440
+ const allSame = fixedWidths.every(w => w === fixedWidths[0]);
441
+ if (allSame && fixedWidths[0] >= 400) {
442
+ node.layout['align-items'] = 'center';
443
+ }
444
+ }
445
+ }
393
446
  // children 재귀
394
447
  if (node.children) {
395
448
  node.children.forEach((child, i) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sangheepark/figma-ds-mcp",
3
- "version": "0.2.12",
3
+ "version": "0.2.14",
4
4
  "description": "MCP server for Code to Figma Bridge — bridges Claude Code to Figma plugin via WebSocket",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",