mirror of
https://github.com/penpot/penpot-exporter-figma-plugin.git
synced 2024-12-22 13:43:03 -05:00
added layout sizing
This commit is contained in:
parent
9053ba9226
commit
da68e0ca3f
13 changed files with 109 additions and 33 deletions
|
@ -9,14 +9,16 @@ const nodeActsAsMask = (node: SceneNode): boolean => {
|
|||
export const transformChildren = async (
|
||||
node: ChildrenMixin,
|
||||
baseX: number = 0,
|
||||
baseY: number = 0
|
||||
baseY: number = 0,
|
||||
reverseChildrenOrder: boolean = false
|
||||
): Promise<Children> => {
|
||||
const maskIndex = node.children.findIndex(nodeActsAsMask);
|
||||
const containsMask = maskIndex !== -1;
|
||||
const children = reverseChildrenOrder ? node.children.slice().reverse() : node.children;
|
||||
|
||||
return {
|
||||
children: containsMask
|
||||
? await translateMaskChildren(node.children, maskIndex, baseX, baseY)
|
||||
: await translateChildren(node.children, baseX, baseY)
|
||||
? await translateMaskChildren(children, maskIndex, baseX, baseY)
|
||||
: await translateChildren(children, baseX, baseY)
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
import {
|
||||
translateLayoutAlignContent,
|
||||
translateLayoutAlignItems,
|
||||
translateLayoutFlexDir,
|
||||
translateLayoutGap,
|
||||
translateLayoutJustifyContent,
|
||||
translateLayoutJustifyItems,
|
||||
translateLayoutPadding,
|
||||
translateLayoutSizing,
|
||||
translateLayoutWrapType
|
||||
} from '@plugin/translators';
|
||||
|
||||
import { LayoutAttributes } from '@ui/lib/types/shapes/layout';
|
||||
import { LayoutAttributes, LayoutChildAttributes } from '@ui/lib/types/shapes/layout';
|
||||
|
||||
export const transformAutoLayout = (node: BaseFrameMixin): LayoutAttributes => {
|
||||
console.log(node);
|
||||
return {
|
||||
layout: node.layoutMode !== 'NONE' ? 'flex' : undefined,
|
||||
layoutFlexDir: translateLayoutFlexDir(node.layoutMode),
|
||||
|
@ -19,7 +21,16 @@ export const transformAutoLayout = (node: BaseFrameMixin): LayoutAttributes => {
|
|||
layoutPadding: translateLayoutPadding(node),
|
||||
layoutJustifyContent: translateLayoutJustifyContent(node),
|
||||
layoutJustifyItems: translateLayoutJustifyItems(node),
|
||||
layoutAlignContent: translateLayoutJustifyContent(node),
|
||||
layoutAlignItems: translateLayoutJustifyItems(node)
|
||||
layoutAlignContent: translateLayoutAlignContent(node),
|
||||
layoutAlignItems: translateLayoutAlignItems(node)
|
||||
};
|
||||
};
|
||||
|
||||
export const transformLayoutSizing = (
|
||||
node: LayoutMixin
|
||||
): Pick<LayoutChildAttributes, 'layoutItemHSizing' | 'layoutItemVSizing'> => {
|
||||
return {
|
||||
layoutItemHSizing: translateLayoutSizing(node.layoutSizingHorizontal),
|
||||
layoutItemVSizing: translateLayoutSizing(node.layoutSizingVertical)
|
||||
};
|
||||
};
|
||||
|
|
|
@ -4,6 +4,7 @@ import {
|
|||
transformBlend,
|
||||
transformDimensionAndPositionFromVectorPath,
|
||||
transformEffects,
|
||||
transformLayoutSizing,
|
||||
transformProportion,
|
||||
transformSceneNode,
|
||||
transformStrokesFromVector
|
||||
|
@ -110,6 +111,7 @@ const transformVectorPath = (
|
|||
...transformDimensionAndPositionFromVectorPath(vectorPath, baseX, baseY),
|
||||
...transformSceneNode(node),
|
||||
...transformBlend(node),
|
||||
...transformProportion(node)
|
||||
...transformProportion(node),
|
||||
...transformLayoutSizing(node)
|
||||
};
|
||||
};
|
||||
|
|
|
@ -5,6 +5,7 @@ import {
|
|||
transformEffects,
|
||||
transformFigmaIds,
|
||||
transformFills,
|
||||
transformLayoutSizing,
|
||||
transformProportion,
|
||||
transformSceneNode,
|
||||
transformStrokes
|
||||
|
@ -30,6 +31,7 @@ export const transformBooleanNode = async (
|
|||
...transformDimensionAndPosition(node, baseX, baseY),
|
||||
...transformSceneNode(node),
|
||||
...transformBlend(node),
|
||||
...transformProportion(node)
|
||||
...transformProportion(node),
|
||||
...transformLayoutSizing(node)
|
||||
};
|
||||
};
|
||||
|
|
|
@ -8,6 +8,7 @@ import {
|
|||
transformEffects,
|
||||
transformFigmaIds,
|
||||
transformFills,
|
||||
transformLayoutSizing,
|
||||
transformProportion,
|
||||
transformSceneNode,
|
||||
transformStrokes
|
||||
|
@ -32,6 +33,7 @@ export const transformComponentNode = async (
|
|||
...transformSceneNode(node),
|
||||
...transformBlend(node),
|
||||
...transformProportion(node),
|
||||
...transformLayoutSizing(node),
|
||||
...transformCornerRadius(node),
|
||||
...(await transformChildren(node, baseX + node.x, baseY + node.y)),
|
||||
...transformDimensionAndPosition(node, baseX, baseY),
|
||||
|
|
|
@ -5,6 +5,7 @@ import {
|
|||
transformEffects,
|
||||
transformFigmaIds,
|
||||
transformFills,
|
||||
transformLayoutSizing,
|
||||
transformProportion,
|
||||
transformRotationAndPosition,
|
||||
transformSceneNode,
|
||||
|
@ -30,6 +31,7 @@ export const transformEllipseNode = (
|
|||
...transformSceneNode(node),
|
||||
...transformBlend(node),
|
||||
...transformProportion(node),
|
||||
...transformLayoutSizing(node),
|
||||
...transformConstraints(node)
|
||||
};
|
||||
};
|
||||
|
|
|
@ -8,6 +8,7 @@ import {
|
|||
transformEffects,
|
||||
transformFigmaIds,
|
||||
transformFills,
|
||||
transformLayoutSizing,
|
||||
transformProportion,
|
||||
transformSceneNode,
|
||||
transformStrokes
|
||||
|
@ -25,8 +26,12 @@ export const transformFrameNode = async (
|
|||
baseY: number
|
||||
): Promise<FrameShape> => {
|
||||
let frameSpecificAttributes: Partial<FrameShape> = {};
|
||||
let reverseChildrenOrder = false;
|
||||
|
||||
if (!isSectionNode(node)) {
|
||||
if (node.layoutMode !== 'NONE') {
|
||||
reverseChildrenOrder = true;
|
||||
}
|
||||
// Figma API does not expose strokes, blend modes, corner radius, or constraint proportions for sections,
|
||||
// they plan to add it in the future. Refactor this when available.
|
||||
frameSpecificAttributes = {
|
||||
|
@ -35,6 +40,7 @@ export const transformFrameNode = async (
|
|||
// @see: https://forum.figma.com/t/add-a-blendmode-property-for-sectionnode/58560
|
||||
...transformBlend(node),
|
||||
...transformProportion(node),
|
||||
...transformLayoutSizing(node),
|
||||
...transformCornerRadius(node),
|
||||
...transformEffects(node),
|
||||
...transformConstraints(node),
|
||||
|
@ -49,7 +55,7 @@ export const transformFrameNode = async (
|
|||
...transformFigmaIds(node),
|
||||
...transformFills(node),
|
||||
...frameSpecificAttributes,
|
||||
...(await transformChildren(node, baseX + node.x, baseY + node.y)),
|
||||
...(await transformChildren(node, baseX + node.x, baseY + node.y, reverseChildrenOrder)),
|
||||
...transformDimensionAndPosition(node, baseX, baseY),
|
||||
...transformSceneNode(node)
|
||||
};
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { remoteComponentLibrary } from '@plugin/RemoteComponentLibrary';
|
||||
import {
|
||||
transformAutoLayout,
|
||||
transformBlend,
|
||||
transformChildren,
|
||||
transformConstraints,
|
||||
|
@ -8,6 +9,7 @@ import {
|
|||
transformEffects,
|
||||
transformFigmaIds,
|
||||
transformFills,
|
||||
transformLayoutSizing,
|
||||
transformProportion,
|
||||
transformSceneNode,
|
||||
transformStrokes
|
||||
|
@ -30,6 +32,11 @@ export const transformInstanceNode = async (
|
|||
await registerExternalComponents(mainComponent);
|
||||
}
|
||||
|
||||
let reverseChildrenOrder = false;
|
||||
if (node.layoutMode !== 'NONE') {
|
||||
reverseChildrenOrder = true;
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'instance',
|
||||
name: node.name,
|
||||
|
@ -43,10 +50,12 @@ export const transformInstanceNode = async (
|
|||
...transformSceneNode(node),
|
||||
...transformBlend(node),
|
||||
...transformProportion(node),
|
||||
...transformLayoutSizing(node),
|
||||
...transformCornerRadius(node),
|
||||
...transformDimensionAndPosition(node, baseX, baseY),
|
||||
...transformConstraints(node),
|
||||
...(await transformChildren(node, baseX + node.x, baseY + node.y))
|
||||
...transformAutoLayout(node),
|
||||
...(await transformChildren(node, baseX + node.x, baseY + node.y, reverseChildrenOrder))
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import {
|
|||
transformEffects,
|
||||
transformFigmaIds,
|
||||
transformFills,
|
||||
transformLayoutSizing,
|
||||
transformProportion,
|
||||
transformSceneNode,
|
||||
transformStrokes,
|
||||
|
@ -34,6 +35,7 @@ export const transformPathNode = (
|
|||
...transformSceneNode(node),
|
||||
...transformBlend(node),
|
||||
...transformProportion(node),
|
||||
...transformLayoutSizing(node),
|
||||
...transformConstraints(node)
|
||||
};
|
||||
};
|
||||
|
|
|
@ -6,6 +6,7 @@ import {
|
|||
transformEffects,
|
||||
transformFigmaIds,
|
||||
transformFills,
|
||||
transformLayoutSizing,
|
||||
transformProportion,
|
||||
transformRotationAndPosition,
|
||||
transformSceneNode,
|
||||
|
@ -31,6 +32,7 @@ export const transformRectangleNode = (
|
|||
...transformSceneNode(node),
|
||||
...transformBlend(node),
|
||||
...transformProportion(node),
|
||||
...transformLayoutSizing(node),
|
||||
...transformCornerRadius(node),
|
||||
...transformConstraints(node)
|
||||
};
|
||||
|
|
|
@ -4,6 +4,7 @@ import {
|
|||
transformDimensionAndPosition,
|
||||
transformEffects,
|
||||
transformFigmaIds,
|
||||
transformLayoutSizing,
|
||||
transformProportion,
|
||||
transformSceneNode,
|
||||
transformStrokes,
|
||||
|
@ -23,6 +24,7 @@ export const transformTextNode = (node: TextNode, baseX: number, baseY: number):
|
|||
...transformSceneNode(node),
|
||||
...transformBlend(node),
|
||||
...transformProportion(node),
|
||||
...transformLayoutSizing(node),
|
||||
...transformStrokes(node),
|
||||
...transformConstraints(node)
|
||||
};
|
||||
|
|
|
@ -4,18 +4,22 @@ import {
|
|||
LayoutFlexDir,
|
||||
LayoutGap,
|
||||
LayoutPadding,
|
||||
LayoutSizing,
|
||||
LayoutWrapType
|
||||
} from '@ui/lib/types/shapes/layout';
|
||||
|
||||
type FigmaLayoutMode = 'NONE' | 'HORIZONTAL' | 'VERTICAL';
|
||||
|
||||
type FigmaWrap = 'NO_WRAP' | 'WRAP';
|
||||
|
||||
type FigmaLayoutSizing = 'FIXED' | 'HUG' | 'FILL';
|
||||
|
||||
export const translateLayoutFlexDir = (layoutMode: FigmaLayoutMode): LayoutFlexDir | undefined => {
|
||||
switch (layoutMode) {
|
||||
case 'HORIZONTAL':
|
||||
return 'row-reverse';
|
||||
return 'row';
|
||||
case 'VERTICAL':
|
||||
return 'column-reverse';
|
||||
return 'column';
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
@ -62,6 +66,19 @@ export const translateLayoutJustifyContent = (node: BaseFrameMixin): JustifyAlig
|
|||
};
|
||||
|
||||
export const translateLayoutJustifyItems = (node: BaseFrameMixin): JustifyAlignItems => {
|
||||
switch (node.primaryAxisAlignItems) {
|
||||
case 'MIN':
|
||||
return 'start';
|
||||
case 'CENTER':
|
||||
return 'center';
|
||||
case 'MAX':
|
||||
return 'end';
|
||||
default:
|
||||
return 'stretch';
|
||||
}
|
||||
};
|
||||
|
||||
export const translateLayoutAlignContent = (node: BaseFrameMixin): JustifyAlignContent => {
|
||||
switch (node.counterAxisAlignItems) {
|
||||
case 'MIN':
|
||||
return 'start';
|
||||
|
@ -73,3 +90,27 @@ export const translateLayoutJustifyItems = (node: BaseFrameMixin): JustifyAlignI
|
|||
return 'stretch';
|
||||
}
|
||||
};
|
||||
|
||||
export const translateLayoutAlignItems = (node: BaseFrameMixin): JustifyAlignItems => {
|
||||
switch (node.counterAxisAlignItems) {
|
||||
case 'MIN':
|
||||
return 'start';
|
||||
case 'CENTER':
|
||||
return 'center';
|
||||
case 'MAX':
|
||||
return 'end';
|
||||
default:
|
||||
return 'stretch';
|
||||
}
|
||||
};
|
||||
|
||||
export const translateLayoutSizing = (sizing: FigmaLayoutSizing): LayoutSizing => {
|
||||
switch (sizing) {
|
||||
case 'FIXED':
|
||||
return 'fix';
|
||||
case 'HUG':
|
||||
return 'auto';
|
||||
case 'FILL':
|
||||
return 'fill';
|
||||
}
|
||||
};
|
||||
|
|
|
@ -2,17 +2,22 @@ import { Uuid } from '@ui/lib/types/utils/uuid';
|
|||
|
||||
export const ITEM_MARGIN_SIMPLE_TYPE: unique symbol = Symbol.for('simple');
|
||||
export const ITEM_MARGIN_MULTIPLE_TYPE: unique symbol = Symbol.for('multiple');
|
||||
export const ITEM_HSIZING_FILL: unique symbol = Symbol.for('fill');
|
||||
export const ITEM_HSIZING_FIX: unique symbol = Symbol.for('fix');
|
||||
export const ITEM_HSIZING_AUTO: unique symbol = Symbol.for('auto');
|
||||
export const ITEM_VSIZING_FILL: unique symbol = Symbol.for('fill');
|
||||
export const ITEM_VSIZING_FIX: unique symbol = Symbol.for('fix');
|
||||
export const ITEM_VSIZING_AUTO: unique symbol = Symbol.for('auto');
|
||||
export const ITEM_SIZING_FILL: unique symbol = Symbol.for('fill');
|
||||
export const ITEM_SIZING_FIX: unique symbol = Symbol.for('fix');
|
||||
export const ITEM_SIZING_AUTO: unique symbol = Symbol.for('auto');
|
||||
export const ITEM_ALIGN_SELF_START: unique symbol = Symbol.for('start');
|
||||
export const ITEM_ALIGN_SELF_END: unique symbol = Symbol.for('end');
|
||||
export const ITEM_ALIGN_SELF_CENTER: unique symbol = Symbol.for('center');
|
||||
export const ITEM_ALIGN_SELF_STRETCH: unique symbol = Symbol.for('stretch');
|
||||
|
||||
export type LayoutSizing =
|
||||
| 'fill'
|
||||
| 'fix'
|
||||
| 'auto'
|
||||
| typeof ITEM_SIZING_FILL
|
||||
| typeof ITEM_SIZING_FIX
|
||||
| typeof ITEM_SIZING_AUTO;
|
||||
|
||||
export type LayoutChildAttributes = {
|
||||
layoutItemMarginType?:
|
||||
| 'simple'
|
||||
|
@ -29,20 +34,8 @@ export type LayoutChildAttributes = {
|
|||
layoutItemMinH?: number;
|
||||
layoutItemMaxW?: number;
|
||||
layoutItemMinW?: number;
|
||||
layoutItemHSizing?:
|
||||
| 'fill'
|
||||
| 'fix'
|
||||
| 'auto'
|
||||
| typeof ITEM_HSIZING_FILL
|
||||
| typeof ITEM_HSIZING_FIX
|
||||
| typeof ITEM_HSIZING_AUTO;
|
||||
layoutItemVSizing?:
|
||||
| 'fill'
|
||||
| 'fix'
|
||||
| 'auto'
|
||||
| typeof ITEM_VSIZING_FILL
|
||||
| typeof ITEM_VSIZING_FIX
|
||||
| typeof ITEM_VSIZING_AUTO;
|
||||
layoutItemHSizing?: LayoutSizing;
|
||||
layoutItemVSizing?: LayoutSizing;
|
||||
layoutItemAlignSelf?:
|
||||
| 'start'
|
||||
| 'end'
|
||||
|
|
Loading…
Reference in a new issue