@sangheepark/figma-ds-mcp 0.2.7 → 0.2.8
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/dist/tools/pipeline-tools.js +39 -5
- package/package.json +1 -1
|
@@ -239,13 +239,18 @@ function enrichSpec(traversal, mapping) {
|
|
|
239
239
|
delete node['_ds_type'];
|
|
240
240
|
}
|
|
241
241
|
// Step 6: CSS → Figma 정규화
|
|
242
|
-
// 6-pre: overflow →
|
|
243
|
-
const
|
|
244
|
-
if (
|
|
242
|
+
// 6-pre: overflow → clip-content 변환 (style 또는 layout 어디에 있든 처리)
|
|
243
|
+
const styleOverflow = node.style && node.style['overflow'];
|
|
244
|
+
if (styleOverflow === 'hidden' || styleOverflow === 'scroll' || styleOverflow === 'auto') {
|
|
245
245
|
node.layout = node.layout || {};
|
|
246
246
|
node.layout['clip-content'] = true;
|
|
247
247
|
delete node.style['overflow'];
|
|
248
248
|
}
|
|
249
|
+
const layoutOverflow = node.layout && node.layout['overflow'];
|
|
250
|
+
if (layoutOverflow === 'hidden' || layoutOverflow === 'scroll' || layoutOverflow === 'auto') {
|
|
251
|
+
node.layout['clip-content'] = true;
|
|
252
|
+
delete node.layout['overflow'];
|
|
253
|
+
}
|
|
249
254
|
// 6-A: CSS-only 속성 필터링 (Figma가 지원하지 않는 CSS 속성 제거)
|
|
250
255
|
if (node.style) {
|
|
251
256
|
for (const key of Object.keys(node.style)) {
|
|
@@ -254,6 +259,25 @@ function enrichSpec(traversal, mapping) {
|
|
|
254
259
|
}
|
|
255
260
|
}
|
|
256
261
|
}
|
|
262
|
+
// 6-A2: layout에서 CSS position 키 → Figma x/y 변환 후 non-layout 키 제거
|
|
263
|
+
if (node.layout) {
|
|
264
|
+
const lay = node.layout;
|
|
265
|
+
// CSS top/left → Figma y/x (absolute positioning만)
|
|
266
|
+
if (lay['positioning'] === 'absolute') {
|
|
267
|
+
if (lay['top'] !== undefined && lay['y'] === undefined) {
|
|
268
|
+
lay['y'] = String(lay['top']);
|
|
269
|
+
}
|
|
270
|
+
if (lay['left'] !== undefined && lay['x'] === undefined) {
|
|
271
|
+
lay['x'] = String(lay['left']);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
// non-layout 키 제거 (top, bottom, left, right, aspect-ratio, overflow 잔존 등)
|
|
275
|
+
for (const key of Object.keys(lay)) {
|
|
276
|
+
if (!LAYOUT_KEYS.has(key)) {
|
|
277
|
+
delete lay[key];
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
257
281
|
// 6-B: direction 기본값 column (children 있는 frame/component에 direction 없으면)
|
|
258
282
|
if ((node.type === 'frame' || node.type === 'component') && node.children && node.children.length > 0) {
|
|
259
283
|
if (!node.layout?.direction) {
|
|
@@ -1156,10 +1180,20 @@ If no reviewNeeded, completes in 1 pass.`, {
|
|
|
1156
1180
|
// Also produce manifest + section files for incremental build
|
|
1157
1181
|
const outputDir = dirname(outputPath);
|
|
1158
1182
|
const manifests = [];
|
|
1159
|
-
|
|
1160
|
-
const manifest = splitSections(
|
|
1183
|
+
if (allPages.length === 1) {
|
|
1184
|
+
const manifest = splitSections(allPages[0], allComponents, outputDir);
|
|
1161
1185
|
manifests.push(manifest);
|
|
1162
1186
|
}
|
|
1187
|
+
else {
|
|
1188
|
+
for (let i = 0; i < allPages.length; i++) {
|
|
1189
|
+
const pageDir = join(outputDir, `page_${i}`);
|
|
1190
|
+
mkdirSync(pageDir, { recursive: true });
|
|
1191
|
+
const manifest = splitSections(allPages[i], allComponents, pageDir);
|
|
1192
|
+
manifests.push(manifest);
|
|
1193
|
+
}
|
|
1194
|
+
// Save combined manifest at root level
|
|
1195
|
+
writeFileSync(join(outputDir, 'manifest.json'), JSON.stringify(manifests, null, 2));
|
|
1196
|
+
}
|
|
1163
1197
|
// Save full specs (legacy format) alongside manifest
|
|
1164
1198
|
if (finalSpecs.length === 1) {
|
|
1165
1199
|
writeFileSync(outputPath, JSON.stringify(finalSpecs[0], null, 2));
|
package/package.json
CHANGED