mirror of
https://github.com/penpot/penpot-exporter-figma-plugin.git
synced 2024-12-22 13:43:03 -05:00
parent
2f11c5f090
commit
4591369e3c
17 changed files with 274 additions and 10 deletions
5
.changeset/neat-badgers-dream.md
Normal file
5
.changeset/neat-badgers-dream.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"penpot-exporter": minor
|
||||
---
|
||||
|
||||
Added support for instances overrides
|
13
plugin-src/OverridesLibrary.ts
Normal file
13
plugin-src/OverridesLibrary.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
class OverridesLibrary {
|
||||
private overrides: Map<string, NodeChangeProperty[]> = new Map();
|
||||
|
||||
public register(nodeId: string, overrides: NodeChangeProperty[]): void {
|
||||
this.overrides.set(nodeId, overrides);
|
||||
}
|
||||
|
||||
public get(nodeId: string): NodeChangeProperty[] | undefined {
|
||||
return this.overrides.get(nodeId);
|
||||
}
|
||||
}
|
||||
|
||||
export const overridesLibrary = new OverridesLibrary();
|
|
@ -7,6 +7,7 @@ export * from './transformEffects';
|
|||
export * from './transformFigmaIds';
|
||||
export * from './transformFills';
|
||||
export * from './transformLayout';
|
||||
export * from './transformOverrides';
|
||||
export * from './transformProportion';
|
||||
export * from './transformRotationAndPosition';
|
||||
export * from './transformSceneNode';
|
||||
|
|
23
plugin-src/transformers/partials/transformOverrides.ts
Normal file
23
plugin-src/transformers/partials/transformOverrides.ts
Normal file
|
@ -0,0 +1,23 @@
|
|||
import { overridesLibrary } from '@plugin/OverridesLibrary';
|
||||
import { syncAttributes } from '@plugin/utils/syncAttributes';
|
||||
|
||||
import { SyncGroups } from '@ui/lib/types/utils/syncGroups';
|
||||
|
||||
export const transformOverrides = (node: SceneNode) => {
|
||||
const overrides = overridesLibrary.get(node.id);
|
||||
if (!overrides) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const touched: SyncGroups[] = [];
|
||||
|
||||
overrides.forEach(override => {
|
||||
if (syncAttributes[override]) {
|
||||
touched.push(...syncAttributes[override]);
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
touched
|
||||
};
|
||||
};
|
|
@ -6,6 +6,7 @@ import {
|
|||
transformFigmaIds,
|
||||
transformFills,
|
||||
transformLayoutAttributes,
|
||||
transformOverrides,
|
||||
transformProportion,
|
||||
transformRotationAndPosition,
|
||||
transformSceneNode,
|
||||
|
@ -33,6 +34,7 @@ export const transformBooleanNode = async (
|
|||
...transformSceneNode(node),
|
||||
...transformBlend(node),
|
||||
...transformProportion(node),
|
||||
...transformLayoutAttributes(node)
|
||||
...transformLayoutAttributes(node),
|
||||
...transformOverrides(node)
|
||||
};
|
||||
};
|
||||
|
|
|
@ -6,6 +6,7 @@ import {
|
|||
transformFigmaIds,
|
||||
transformFills,
|
||||
transformLayoutAttributes,
|
||||
transformOverrides,
|
||||
transformProportion,
|
||||
transformRotationAndPosition,
|
||||
transformSceneNode,
|
||||
|
@ -28,6 +29,7 @@ export const transformEllipseNode = (node: EllipseNode, baseRotation: number): C
|
|||
...transformBlend(node),
|
||||
...transformProportion(node),
|
||||
...transformLayoutAttributes(node),
|
||||
...transformConstraints(node)
|
||||
...transformConstraints(node),
|
||||
...transformOverrides(node)
|
||||
};
|
||||
};
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
transformFigmaIds,
|
||||
transformFills,
|
||||
transformLayoutAttributes,
|
||||
transformOverrides,
|
||||
transformProportion,
|
||||
transformRotationAndPosition,
|
||||
transformSceneNode,
|
||||
|
@ -63,6 +64,7 @@ export const transformFrameNode = async (
|
|||
...frameSpecificAttributes,
|
||||
...transformDimension(node),
|
||||
...(await transformChildren(node, rotation)),
|
||||
...transformSceneNode(node)
|
||||
...transformSceneNode(node),
|
||||
...transformOverrides(node)
|
||||
};
|
||||
};
|
||||
|
|
|
@ -3,6 +3,7 @@ import {
|
|||
transformDimension,
|
||||
transformEffects,
|
||||
transformFigmaIds,
|
||||
transformOverrides,
|
||||
transformRotationAndPosition,
|
||||
transformSceneNode
|
||||
} from '@plugin/transformers/partials';
|
||||
|
@ -19,7 +20,8 @@ export const transformGroupNode = async (
|
|||
...transformGroupNodeLike(node, baseRotation),
|
||||
...transformEffects(node),
|
||||
...transformBlend(node),
|
||||
...(await transformChildren(node, baseRotation))
|
||||
...(await transformChildren(node, baseRotation)),
|
||||
...transformOverrides(node)
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { overridesLibrary } from '@plugin/OverridesLibrary';
|
||||
import { remoteComponentLibrary } from '@plugin/RemoteComponentLibrary';
|
||||
import {
|
||||
transformAutoLayout,
|
||||
|
@ -10,6 +11,7 @@ import {
|
|||
transformFigmaIds,
|
||||
transformFills,
|
||||
transformLayoutAttributes,
|
||||
transformOverrides,
|
||||
transformProportion,
|
||||
transformRotationAndPosition,
|
||||
transformSceneNode,
|
||||
|
@ -32,6 +34,12 @@ export const transformInstanceNode = async (
|
|||
registerExternalComponents(mainComponent);
|
||||
}
|
||||
|
||||
if (node.overrides.length > 0) {
|
||||
node.overrides.forEach(override =>
|
||||
overridesLibrary.register(override.id, override.overriddenFields)
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'instance',
|
||||
name: node.name,
|
||||
|
@ -51,7 +59,8 @@ export const transformInstanceNode = async (
|
|||
...transformRotationAndPosition(node, baseRotation),
|
||||
...transformConstraints(node),
|
||||
...transformAutoLayout(node),
|
||||
...(await transformChildren(node, node.rotation + baseRotation))
|
||||
...(await transformChildren(node, node.rotation + baseRotation)),
|
||||
...transformOverrides(node)
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import {
|
|||
transformEffects,
|
||||
transformFigmaIds,
|
||||
transformLayoutAttributes,
|
||||
transformOverrides,
|
||||
transformProportion,
|
||||
transformSceneNode,
|
||||
transformStrokes
|
||||
|
@ -30,6 +31,7 @@ export const transformLineNode = (node: LineNode, baseRotation: number): PathSha
|
|||
...transformBlend(node),
|
||||
...transformProportion(node),
|
||||
...transformLayoutAttributes(node),
|
||||
...transformConstraints(node)
|
||||
...transformConstraints(node),
|
||||
...transformOverrides(node)
|
||||
};
|
||||
};
|
||||
|
|
|
@ -5,6 +5,7 @@ import {
|
|||
transformFigmaIds,
|
||||
transformFills,
|
||||
transformLayoutAttributes,
|
||||
transformOverrides,
|
||||
transformProportion,
|
||||
transformSceneNode,
|
||||
transformStrokes
|
||||
|
@ -29,6 +30,7 @@ export const transformPathNode = (
|
|||
...transformBlend(node),
|
||||
...transformProportion(node),
|
||||
...transformLayoutAttributes(node),
|
||||
...transformConstraints(node)
|
||||
...transformConstraints(node),
|
||||
...transformOverrides(node)
|
||||
};
|
||||
};
|
||||
|
|
|
@ -7,6 +7,7 @@ import {
|
|||
transformFigmaIds,
|
||||
transformFills,
|
||||
transformLayoutAttributes,
|
||||
transformOverrides,
|
||||
transformProportion,
|
||||
transformRotationAndPosition,
|
||||
transformSceneNode,
|
||||
|
@ -30,6 +31,7 @@ export const transformRectangleNode = (node: RectangleNode, baseRotation: number
|
|||
...transformProportion(node),
|
||||
...transformLayoutAttributes(node),
|
||||
...transformCornerRadius(node),
|
||||
...transformConstraints(node)
|
||||
...transformConstraints(node),
|
||||
...transformOverrides(node)
|
||||
};
|
||||
};
|
||||
|
|
|
@ -5,6 +5,7 @@ import {
|
|||
transformEffects,
|
||||
transformFigmaIds,
|
||||
transformLayoutAttributes,
|
||||
transformOverrides,
|
||||
transformProportion,
|
||||
transformRotationAndPosition,
|
||||
transformSceneNode,
|
||||
|
@ -28,6 +29,7 @@ export const transformTextNode = (node: TextNode, baseRotation: number): TextSha
|
|||
...transformProportion(node),
|
||||
...transformLayoutAttributes(node),
|
||||
...transformStrokes(node),
|
||||
...transformConstraints(node)
|
||||
...transformConstraints(node),
|
||||
...transformOverrides(node)
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import {
|
||||
transformConstraints,
|
||||
transformFigmaIds,
|
||||
transformOverrides,
|
||||
transformVectorPaths
|
||||
} from '@plugin/transformers/partials';
|
||||
|
||||
|
@ -26,7 +27,8 @@ export const transformVectorNode = (
|
|||
...children[0],
|
||||
name: node.name,
|
||||
...transformFigmaIds(node),
|
||||
...transformConstraints(node)
|
||||
...transformConstraints(node),
|
||||
...transformOverrides(node)
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -34,6 +36,7 @@ export const transformVectorNode = (
|
|||
...transformGroupNodeLike(node, baseRotation),
|
||||
...transformFigmaIds(node),
|
||||
...transformConstraints(node),
|
||||
...transformOverrides(node),
|
||||
children
|
||||
};
|
||||
};
|
||||
|
|
150
plugin-src/utils/syncAttributes.ts
Normal file
150
plugin-src/utils/syncAttributes.ts
Normal file
|
@ -0,0 +1,150 @@
|
|||
import { SyncGroups } from '@ui/lib/types/utils/syncGroups';
|
||||
|
||||
export type SyncAttributes = {
|
||||
[key in NodeChangeProperty]: SyncGroups[];
|
||||
};
|
||||
|
||||
export const syncAttributes: SyncAttributes = {
|
||||
name: [':name-group'],
|
||||
fills: [':fill-group'],
|
||||
backgrounds: [':fill-group'],
|
||||
fillStyleId: [':fill-group'],
|
||||
backgroundStyleId: [':fill-group'],
|
||||
textBackground: [':fill-group'],
|
||||
visible: [':visibility-group'],
|
||||
locked: [':modifiable-group'],
|
||||
fontName: [':text-font-group', ':content-group'],
|
||||
fontSize: [':text-font-group', ':content-group'],
|
||||
textCase: [':text-font-group', ':content-group'],
|
||||
textDecoration: [':text-font-group', ':content-group'],
|
||||
textStyleId: [':text-font-group', ':content-group'],
|
||||
characters: [':text-display-group', ':content-group'],
|
||||
styledTextSegments: [':text-display-group', ':content-group'],
|
||||
lineHeight: [':text-display-group', ':content-group'],
|
||||
leadingTrim: [':text-display-group', ':content-group'],
|
||||
paragraphIndent: [':text-display-group', ':content-group'],
|
||||
paragraphSpacing: [':text-display-group', ':content-group'],
|
||||
listSpacing: [':text-display-group', ':content-group'],
|
||||
hangingPunctuation: [':text-display-group', ':content-group'],
|
||||
hangingList: [':text-display-group', ':content-group'],
|
||||
letterSpacing: [':text-display-group', ':content-group'],
|
||||
textAlignHorizontal: [':text-display-group', ':content-group'],
|
||||
textAlignVertical: [':text-display-group', ':content-group'],
|
||||
textAutoResize: [':text-display-group', ':content-group'],
|
||||
text: [':text-display-group', ':content-group'],
|
||||
strokes: [':stroke-group'],
|
||||
strokeWeight: [':stroke-group'],
|
||||
strokeAlign: [':stroke-group'],
|
||||
strokeCap: [':stroke-group'],
|
||||
strokeJoin: [':stroke-group'],
|
||||
strokeMiterLimit: [':stroke-group'],
|
||||
dashPattern: [':stroke-group'],
|
||||
strokeStyleId: [':stroke-group'],
|
||||
stokeTopWeight: [':stroke-group'],
|
||||
strokeBottomWeight: [':stroke-group'],
|
||||
strokeLeftWeight: [':stroke-group'],
|
||||
strokeRightWeight: [':stroke-group'],
|
||||
connectorStartStrokeCap: [':stroke-group'],
|
||||
connectorEndStrokeCap: [':stroke-group'],
|
||||
innerRadius: [':radius-group'],
|
||||
topLeftRadius: [':radius-group'],
|
||||
topRightRadius: [':radius-group'],
|
||||
bottomLeftRadius: [':radius-group'],
|
||||
bottomRightRadius: [':radius-group'],
|
||||
cornerRadius: [':radius-group'],
|
||||
cornerSmoothing: [':radius-group'],
|
||||
vectorNetwork: [':geometry-group'],
|
||||
pointCount: [':geometry-group'],
|
||||
width: [':geometry-group'],
|
||||
height: [':geometry-group'],
|
||||
guides: [':geometry-group'],
|
||||
arcData: [':geometry-group'],
|
||||
constrainProportions: [':geometry-group'],
|
||||
handleMirroring: [':geometry-group'],
|
||||
relativeTransform: [':geometry-group'],
|
||||
x: [':geometry-group'],
|
||||
y: [':geometry-group'],
|
||||
rotation: [':geometry-group'],
|
||||
type: [':geometry-group'],
|
||||
shapeType: [':geometry-group'],
|
||||
connectorStart: [':geometry-group'],
|
||||
connectorEnd: [':geometry-group'],
|
||||
connectorLineType: [':geometry-group'],
|
||||
opacity: [':layer-effects-group'],
|
||||
blendMode: [':layer-effects-group'],
|
||||
effects: [':shadow-group', ':blur-group'],
|
||||
effectStyleId: [':shadow-group', ':blur-group'],
|
||||
isMask: [':mask-group'],
|
||||
clipsContent: [':mask-group'],
|
||||
maskType: [':mask-group'],
|
||||
constraints: [':constraints-group'],
|
||||
booleanOperation: [':bool-group'],
|
||||
exportSettings: [':exports-group'],
|
||||
gridStyleId: [':grids-group'],
|
||||
layoutMode: [':layout-container', ':layout-flex-dir'],
|
||||
layoutAlign: [':layout-align-content', ':layout-align-items'],
|
||||
itemSpacing: [':layout-gap'],
|
||||
paddingLeft: [':layout-padding'],
|
||||
paddingTop: [':layout-padding'],
|
||||
paddingRight: [':layout-padding'],
|
||||
paddingBottom: [':layout-padding'],
|
||||
layoutGrids: [
|
||||
':layout-grid-cells',
|
||||
':layout-grid-columns',
|
||||
':layout-grid-dir',
|
||||
':layout-grid-rows'
|
||||
],
|
||||
layoutWrap: [':layout-wrap-type'],
|
||||
overflowDirection: [':layout-item-align-self'],
|
||||
counterAxisSizingMode: [':layout-item-h-sizing'],
|
||||
primaryAxisSizingMode: [':layout-item-v-sizing'],
|
||||
primaryAxisAlignItems: [
|
||||
':layout-item-align-self',
|
||||
':layout-justify-items',
|
||||
':layout-justify-content',
|
||||
':layout-gap'
|
||||
],
|
||||
counterAxisAlignItems: [
|
||||
':layout-item-align-self',
|
||||
':layout-align-content',
|
||||
':layout-align-items'
|
||||
],
|
||||
layoutGrow: [':layout-item-h-sizing'],
|
||||
layoutPositioning: [':layout-item-absolute'],
|
||||
itemReverseZIndex: [':layout-item-z-index'],
|
||||
|
||||
// @TODO: not supported yet
|
||||
textTruncation: [],
|
||||
minWidth: [],
|
||||
minHeight: [],
|
||||
maxWidth: [],
|
||||
maxLines: [],
|
||||
maxHeight: [],
|
||||
counterAxisSpacing: [],
|
||||
counterAxisAlignContent: [],
|
||||
openTypeFeatures: [],
|
||||
authorVisible: [],
|
||||
parent: [],
|
||||
pluginData: [],
|
||||
autoRename: [],
|
||||
overlayPositionType: [],
|
||||
overlayBackgroundInteraction: [],
|
||||
overlayBackground: [],
|
||||
prototypeStartNode: [],
|
||||
prototypeBackgrounds: [],
|
||||
expanded: [],
|
||||
description: [],
|
||||
hyperlink: [],
|
||||
mediaData: [],
|
||||
reactions: [],
|
||||
flowStartingPoints: [],
|
||||
codeLanguage: [],
|
||||
widgetSyncedState: [],
|
||||
componentPropertyDefinitions: [],
|
||||
componentPropertyReferences: [],
|
||||
componentProperties: [],
|
||||
embedData: [],
|
||||
linkUnfurlData: [],
|
||||
authorName: [],
|
||||
code: []
|
||||
};
|
|
@ -9,6 +9,7 @@ import { Point } from '@ui/lib/types/utils/point';
|
|||
import { Selrect } from '@ui/lib/types/utils/selrect';
|
||||
import { Shadow } from '@ui/lib/types/utils/shadow';
|
||||
import { Stroke } from '@ui/lib/types/utils/stroke';
|
||||
import { SyncGroups } from '@ui/lib/types/utils/syncGroups';
|
||||
import { Uuid } from '@ui/lib/types/utils/uuid';
|
||||
|
||||
export type ShapeBaseAttributes = {
|
||||
|
@ -74,6 +75,7 @@ export type ShapeAttributes = {
|
|||
shadow?: Shadow[];
|
||||
blur?: Blur;
|
||||
growType?: GrowType;
|
||||
touched?: SyncGroups[];
|
||||
};
|
||||
|
||||
export type ShapeGeomAttributes = {
|
||||
|
|
42
ui-src/lib/types/utils/syncGroups.ts
Normal file
42
ui-src/lib/types/utils/syncGroups.ts
Normal file
|
@ -0,0 +1,42 @@
|
|||
export type SyncGroups =
|
||||
| ':name-group'
|
||||
| ':fill-group'
|
||||
| ':content-group'
|
||||
| ':visibility-group'
|
||||
| ':modifiable-group'
|
||||
| ':text-font-group'
|
||||
| ':text-display-group'
|
||||
| ':stroke-group'
|
||||
| ':radius-group'
|
||||
| ':geometry-group'
|
||||
| ':layer-effects-group'
|
||||
| ':shadow-group'
|
||||
| ':blur-group'
|
||||
| ':mask-group'
|
||||
| ':constraints-group'
|
||||
| ':bool-group'
|
||||
| ':exports-group'
|
||||
| ':grids-group'
|
||||
| ':layout-container'
|
||||
| ':layout-align-content'
|
||||
| ':layout-align-items'
|
||||
| ':layout-flex-dir'
|
||||
| ':layout-gap'
|
||||
| ':layout-justify-content'
|
||||
| ':layout-justify-items'
|
||||
| ':layout-wrap-type'
|
||||
| ':layout-padding'
|
||||
| ':layout-grid-dir'
|
||||
| ':layout-grid-rows'
|
||||
| ':layout-grid-columns'
|
||||
| ':layout-grid-cells'
|
||||
| ':layout-item-margin'
|
||||
| ':layout-item-h-sizing'
|
||||
| ':layout-item-v-sizing'
|
||||
| ':layout-item-max-h'
|
||||
| ':layout-item-min-h'
|
||||
| ':layout-item-max-w'
|
||||
| ':layout-item-min-w'
|
||||
| ':layout-item-absolute'
|
||||
| ':layout-item-z-index'
|
||||
| ':layout-item-align-self';
|
Loading…
Reference in a new issue