0
Fork 0
mirror of https://github.com/penpot/penpot-exporter-figma-plugin.git synced 2024-12-21 21:23:06 -05:00

Remove symbols when possible (#173)

* remove symbols for blend mode

* remove symbol for gradients

* optimize symbols for path contents

* optimize code

* remove symbols
This commit is contained in:
Jordi Sala Morales 2024-06-18 11:20:51 +02:00 committed by GitHub
parent 8697902e08
commit 738ebfeffe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 122 additions and 313 deletions

View file

@ -8,7 +8,7 @@ export type PenpotPage = {
} & Children;
export type PenpotPageOptions = {
background?: string; // hex color
background?: string;
savedGrids?: SavedGrids;
flows?: Flow[];
guides?: { [uuid: Uuid]: Guide };

View file

@ -1,29 +1,9 @@
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_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 LayoutSizing = 'fill' | 'fix' | 'auto';
export type LayoutChildAttributes = {
'layoutItemMarginType'?:
| 'simple'
| 'multiple'
| typeof ITEM_MARGIN_SIMPLE_TYPE
| typeof ITEM_MARGIN_MULTIPLE_TYPE;
'layoutItemMarginType'?: 'simple' | 'multiple';
'layoutItemMargin'?: {
m1?: number;
m2?: number;
@ -36,15 +16,7 @@ export type LayoutChildAttributes = {
'layoutItemMinW'?: number;
'layoutItemH-Sizing'?: LayoutSizing;
'layoutItemV-Sizing'?: LayoutSizing;
'layoutItemAlignSelf'?:
| 'start'
| 'end'
| 'center'
| 'stretch'
| typeof ITEM_ALIGN_SELF_START
| typeof ITEM_ALIGN_SELF_END
| typeof ITEM_ALIGN_SELF_CENTER
| typeof ITEM_ALIGN_SELF_STRETCH;
'layoutItemAlignSelf'?: 'start' | 'end' | 'center' | 'stretch';
'layoutItemAbsolute'?: boolean;
'layoutItemZIndex'?: number;
};

View file

@ -1,20 +1,3 @@
export const BLEND_MODE_NORMAL: unique symbol = Symbol.for('normal');
export const BLEND_MODE_DARKEN: unique symbol = Symbol.for('darken');
export const BLEND_MODE_MULTIPLY: unique symbol = Symbol.for('multiply');
export const BLEND_MODE_COLOR_BURN: unique symbol = Symbol.for('color-burn');
export const BLEND_MODE_LIGHTEN: unique symbol = Symbol.for('lighten');
export const BLEND_MODE_SCREEN: unique symbol = Symbol.for('screen');
export const BLEND_MODE_COLOR_DODGE: unique symbol = Symbol.for('color-dodge');
export const BLEND_MODE_OVERLAY: unique symbol = Symbol.for('overlay');
export const BLEND_MODE_SOFT_LIGHT: unique symbol = Symbol.for('soft-light');
export const BLEND_MODE_HARD_LIGHT: unique symbol = Symbol.for('hard-light');
export const BLEND_MODE_DIFFERENCE: unique symbol = Symbol.for('difference');
export const BLEND_MODE_EXCLUSION: unique symbol = Symbol.for('exclusion');
export const BLEND_MODE_HUE: unique symbol = Symbol.for('hue');
export const BLEND_MODE_SATURATION: unique symbol = Symbol.for('saturation');
export const BLEND_MODE_COLOR: unique symbol = Symbol.for('color');
export const BLEND_MODE_LUMINOSITY: unique symbol = Symbol.for('luminosity');
export type BlendMode =
| 'normal'
| 'darken'
@ -31,20 +14,4 @@ export type BlendMode =
| 'hue'
| 'saturation'
| 'color'
| 'luminosity'
| typeof BLEND_MODE_NORMAL
| typeof BLEND_MODE_DARKEN
| typeof BLEND_MODE_MULTIPLY
| typeof BLEND_MODE_COLOR_BURN
| typeof BLEND_MODE_LIGHTEN
| typeof BLEND_MODE_SCREEN
| typeof BLEND_MODE_COLOR_DODGE
| typeof BLEND_MODE_OVERLAY
| typeof BLEND_MODE_SOFT_LIGHT
| typeof BLEND_MODE_HARD_LIGHT
| typeof BLEND_MODE_DIFFERENCE
| typeof BLEND_MODE_EXCLUSION
| typeof BLEND_MODE_HUE
| typeof BLEND_MODE_SATURATION
| typeof BLEND_MODE_COLOR
| typeof BLEND_MODE_LUMINOSITY;
| 'luminosity';

View file

@ -7,9 +7,9 @@ export type Color = {
name?: string;
path?: string;
value?: string;
color?: string; // hex color
color?: string;
opacity?: number;
modifiedAt?: string; //@TODO: check this attribute in penpot
modifiedAt?: string;
refId?: Uuid;
refFile?: Uuid;
gradient?: Gradient;

View file

@ -1,6 +1,4 @@
export type Export = {
// @TODO: in Penpot this is of type :keyword
// check if it makes sense
type: string;
scale: number;
suffix: string;

View file

@ -1,8 +1,5 @@
export const LINEAR_TYPE: unique symbol = Symbol.for('linear');
export const RADIAL_TYPE: unique symbol = Symbol.for('radial');
export type Gradient = {
type: 'linear' | 'radial' | typeof LINEAR_TYPE | typeof RADIAL_TYPE; // symbol
type: 'linear' | 'radial';
startX: number;
startY: number;
endX: number;

View file

@ -39,6 +39,6 @@ type SquareParams = {
};
type GridColor = {
color: string; // hex color
color: string;
opacity: number;
};

View file

@ -2,34 +2,22 @@ import { PenpotFile } from '@ui/lib/types/penpotFile';
import { FrameShape } from '@ui/lib/types/shapes/frameShape';
import { Uuid } from '@ui/lib/types/utils/uuid';
import { parseFigmaId } from '@ui/parser';
import { symbolBlendMode, symbolFills, symbolStrokes } from '@ui/parser/creators/symbols';
import { symbolFills, symbolStrokes } from '@ui/parser/creators/symbols';
import { createItems } from '.';
export const createArtboard = (
file: PenpotFile,
{
type,
fills,
strokes,
blendMode,
children = [],
figmaId,
figmaRelatedId,
shapeRef,
...rest
}: FrameShape
{ type, children = [], figmaId, figmaRelatedId, ...shape }: FrameShape
): Uuid | undefined => {
const id = parseFigmaId(file, figmaId);
file.addArtboard({
id,
shapeRef: shapeRef ?? parseFigmaId(file, figmaRelatedId, true),
fills: symbolFills(fills),
strokes: symbolStrokes(strokes),
blendMode: symbolBlendMode(blendMode),
...rest
});
shape.id = id;
shape.shapeRef ??= parseFigmaId(file, figmaRelatedId, true);
shape.fills = symbolFills(shape.fills);
shape.strokes = symbolStrokes(shape.strokes);
file.addArtboard(shape);
createItems(file, children);

View file

@ -1,38 +1,21 @@
import { PenpotFile } from '@ui/lib/types/penpotFile';
import { BoolShape } from '@ui/lib/types/shapes/boolShape';
import { parseFigmaId } from '@ui/parser';
import {
symbolBlendMode,
symbolBoolType,
symbolFills,
symbolStrokes
} from '@ui/parser/creators/symbols';
import { symbolBoolType, symbolFills, symbolStrokes } from '@ui/parser/creators/symbols';
import { createItems } from '.';
export const createBool = (
file: PenpotFile,
{
type,
fills,
strokes,
boolType,
blendMode,
figmaId,
figmaRelatedId,
children = [],
...rest
}: BoolShape
{ type, figmaId, figmaRelatedId, children = [], ...shape }: BoolShape
) => {
file.addBool({
id: parseFigmaId(file, figmaId),
shapeRef: parseFigmaId(file, figmaRelatedId, true),
fills: symbolFills(fills),
strokes: symbolStrokes(strokes),
blendMode: symbolBlendMode(blendMode),
boolType: symbolBoolType(boolType),
...rest
});
shape.id = parseFigmaId(file, figmaId);
shape.shapeRef = parseFigmaId(file, figmaRelatedId, true);
shape.fills = symbolFills(shape.fills);
shape.strokes = symbolStrokes(shape.strokes);
shape.boolType = symbolBoolType(shape.boolType);
file.addBool(shape);
createItems(file, children);

View file

@ -1,18 +1,16 @@
import { PenpotFile } from '@ui/lib/types/penpotFile';
import { CircleShape } from '@ui/lib/types/shapes/circleShape';
import { parseFigmaId } from '@ui/parser';
import { symbolBlendMode, symbolFills, symbolStrokes } from '@ui/parser/creators/symbols';
import { symbolFills, symbolStrokes } from '@ui/parser/creators/symbols';
export const createCircle = (
file: PenpotFile,
{ type, fills, strokes, blendMode, figmaId, figmaRelatedId, ...rest }: CircleShape
{ type, figmaId, figmaRelatedId, ...shape }: CircleShape
) => {
file.createCircle({
id: parseFigmaId(file, figmaId),
shapeRef: parseFigmaId(file, figmaRelatedId, true),
fills: symbolFills(fills),
strokes: symbolStrokes(strokes),
blendMode: symbolBlendMode(blendMode),
...rest
});
shape.id = parseFigmaId(file, figmaId);
shape.shapeRef = parseFigmaId(file, figmaRelatedId, true);
shape.fills = symbolFills(shape.fills);
shape.strokes = symbolStrokes(shape.strokes);
file.createCircle(shape);
};

View file

@ -8,21 +8,20 @@ import { createArtboard } from '.';
export const createComponent = (file: PenpotFile, { figmaId }: ComponentRoot) => {
const component = componentsLibrary.get(figmaId);
if (!component) {
return;
}
const uiComponent = uiComponents.get(figmaId);
const componentId = uiComponent?.componentId ?? file.newId();
const componentId = getComponentId(file, figmaId);
const { type, ...shape } = component;
const frameId = createArtboard(file, {
...component,
componentFile: file.getId(),
componentId,
componentRoot: true,
mainInstance: true,
type: 'frame'
});
shape.componentFile = file.getId();
shape.componentId = componentId;
shape.componentRoot = true;
shape.mainInstance = true;
const frameId = createArtboard(file, shape);
if (!frameId) {
return;
@ -35,3 +34,9 @@ export const createComponent = (file: PenpotFile, { figmaId }: ComponentRoot) =>
mainInstanceId: frameId
});
};
const getComponentId = (file: PenpotFile, figmaId: string) => {
const uiComponent = uiComponents.get(figmaId);
return uiComponent?.componentId ?? file.newId();
};

View file

@ -13,31 +13,37 @@ export const createComponentInstance = (
figmaId,
figmaRelatedId,
isComponentRoot,
...rest
...shape
}: ComponentInstance
) => {
let uiComponent = uiComponents.get(mainComponentFigmaId);
const uiComponent =
uiComponents.get(mainComponentFigmaId) ?? createUiComponent(file, mainComponentFigmaId);
if (!uiComponent) {
const mainInstanceId = parseFigmaId(file, mainComponentFigmaId);
if (!mainInstanceId) {
return;
}
uiComponent = {
componentId: file.newId(),
componentFigmaId: mainComponentFigmaId,
mainInstanceId
};
uiComponents.register(mainComponentFigmaId, uiComponent);
return;
}
createArtboard(file, {
...rest,
shapeRef: uiComponent.mainInstanceId,
componentFile: file.getId(),
componentRoot: isComponentRoot,
componentId: uiComponent.componentId,
type: 'frame'
});
shape.shapeRef = uiComponent.mainInstanceId;
shape.componentFile = file.getId();
shape.componentRoot = isComponentRoot;
shape.componentId = uiComponent.componentId;
createArtboard(file, shape);
};
const createUiComponent = (file: PenpotFile, mainComponentFigmaId: string) => {
const mainInstanceId = parseFigmaId(file, mainComponentFigmaId);
if (!mainInstanceId) {
return;
}
const uiComponent = {
componentId: file.newId(),
componentFigmaId: mainComponentFigmaId,
mainInstanceId
};
uiComponents.register(mainComponentFigmaId, uiComponent);
return uiComponent;
};

View file

@ -3,7 +3,7 @@ import { sleep } from '@plugin/utils/sleep';
import { sendMessage } from '@ui/context';
import { PenpotFile } from '@ui/lib/types/penpotFile';
import { symbolBlendMode, symbolFills, symbolStrokes } from '@ui/parser/creators/symbols';
import { symbolFills, symbolStrokes } from '@ui/parser/creators/symbols';
import { UiComponent, uiComponents } from '@ui/parser/libraries';
import { createItems } from '.';
@ -41,21 +41,19 @@ const createComponentLibrary = async (file: PenpotFile, uiComponent: UiComponent
return;
}
const { children = [], fills, strokes, blendMode, ...rest } = component;
const { children = [], ...shape } = component;
file.startComponent({
...rest,
fills: symbolFills(fills),
strokes: symbolStrokes(strokes),
blendMode: symbolBlendMode(blendMode),
id: uiComponent.componentId,
componentId: uiComponent.componentId,
mainInstancePage: uiComponent.mainInstancePage,
mainInstanceId: uiComponent.mainInstanceId,
componentRoot: true,
mainInstance: true,
componentFile: file.getId()
});
shape.fills = symbolFills(shape.fills);
shape.strokes = symbolStrokes(shape.strokes);
shape.id = uiComponent.componentId;
shape.componentId = uiComponent.componentId;
shape.mainInstancePage = uiComponent.mainInstancePage;
shape.mainInstanceId = uiComponent.mainInstanceId;
shape.componentRoot = true;
shape.mainInstance = true;
shape.componentFile = file.getId();
file.startComponent(shape);
createItems(file, children);

View file

@ -1,20 +1,17 @@
import { PenpotFile } from '@ui/lib/types/penpotFile';
import { GroupShape } from '@ui/lib/types/shapes/groupShape';
import { parseFigmaId } from '@ui/parser';
import { symbolBlendMode } from '@ui/parser/creators/symbols';
import { createItems } from '.';
export const createGroup = (
file: PenpotFile,
{ type, blendMode, children = [], figmaId, figmaRelatedId, ...rest }: GroupShape
{ type, children = [], figmaId, figmaRelatedId, ...shape }: GroupShape
) => {
file.addGroup({
id: parseFigmaId(file, figmaId),
shapeRef: parseFigmaId(file, figmaRelatedId, true),
blendMode: symbolBlendMode(blendMode),
...rest
});
shape.id = parseFigmaId(file, figmaId);
shape.shapeRef = parseFigmaId(file, figmaRelatedId, true);
file.addGroup(shape);
createItems(file, children);

View file

@ -1,24 +1,17 @@
import { PenpotFile } from '@ui/lib/types/penpotFile';
import { PathShape } from '@ui/lib/types/shapes/pathShape';
import { parseFigmaId } from '@ui/parser';
import {
symbolBlendMode,
symbolFills,
symbolPathContent,
symbolStrokes
} from '@ui/parser/creators/symbols';
import { symbolFills, symbolPathContent, symbolStrokes } from '@ui/parser/creators/symbols';
export const createPath = (
file: PenpotFile,
{ type, fills, strokes, blendMode, content, figmaId, figmaRelatedId, ...rest }: PathShape
{ type, figmaId, figmaRelatedId, ...shape }: PathShape
) => {
file.createPath({
id: parseFigmaId(file, figmaId),
shapeRef: parseFigmaId(file, figmaRelatedId, true),
fills: symbolFills(fills),
strokes: symbolStrokes(strokes),
blendMode: symbolBlendMode(blendMode),
content: symbolPathContent(content),
...rest
});
shape.id = parseFigmaId(file, figmaId);
shape.shapeRef = parseFigmaId(file, figmaRelatedId, true);
shape.fills = symbolFills(shape.fills);
shape.strokes = symbolStrokes(shape.strokes);
shape.content = symbolPathContent(shape.content);
file.createPath(shape);
};

View file

@ -1,18 +1,16 @@
import { PenpotFile } from '@ui/lib/types/penpotFile';
import { RectShape } from '@ui/lib/types/shapes/rectShape';
import { parseFigmaId } from '@ui/parser';
import { symbolBlendMode, symbolFills, symbolStrokes } from '@ui/parser/creators/symbols';
import { symbolFills, symbolStrokes } from '@ui/parser/creators/symbols';
export const createRectangle = (
file: PenpotFile,
{ type, fills, strokes, blendMode, figmaId, figmaRelatedId, ...rest }: RectShape
{ type, figmaId, figmaRelatedId, ...shape }: RectShape
) => {
file.createRect({
id: parseFigmaId(file, figmaId),
shapeRef: parseFigmaId(file, figmaRelatedId, true),
fills: symbolFills(fills),
strokes: symbolStrokes(strokes),
blendMode: symbolBlendMode(blendMode),
...rest
});
shape.id = parseFigmaId(file, figmaId);
shape.shapeRef = parseFigmaId(file, figmaRelatedId, true);
shape.fills = symbolFills(shape.fills);
shape.strokes = symbolStrokes(shape.strokes);
file.createRect(shape);
};

View file

@ -1,20 +1,18 @@
import { PenpotFile } from '@ui/lib/types/penpotFile';
import { TextContent, TextShape } from '@ui/lib/types/shapes/textShape';
import { parseFigmaId } from '@ui/parser';
import { symbolBlendMode, symbolFills, symbolStrokes } from '@ui/parser/creators/symbols';
import { symbolFills, symbolStrokes } from '@ui/parser/creators/symbols';
export const createText = (
file: PenpotFile,
{ type, blendMode, strokes, figmaId, content, figmaRelatedId, ...rest }: TextShape
{ type, figmaId, figmaRelatedId, ...shape }: TextShape
) => {
file.createText({
id: parseFigmaId(file, figmaId),
shapeRef: parseFigmaId(file, figmaRelatedId, true),
content: parseContent(content),
blendMode: symbolBlendMode(blendMode),
strokes: symbolStrokes(strokes),
...rest
});
shape.id = parseFigmaId(file, figmaId);
shape.shapeRef = parseFigmaId(file, figmaRelatedId, true);
shape.content = parseContent(shape.content);
shape.strokes = symbolStrokes(shape.strokes);
file.createText(shape);
};
const parseContent = (content: TextContent | undefined): TextContent | undefined => {

View file

@ -1,4 +1,3 @@
export * from './symbolBlendMode';
export * from './symbolBoolType';
export * from './symbolFills';
export * from './symbolPathContent';

View file

@ -1,60 +0,0 @@
import {
BLEND_MODE_COLOR,
BLEND_MODE_COLOR_BURN,
BLEND_MODE_COLOR_DODGE,
BLEND_MODE_DARKEN,
BLEND_MODE_DIFFERENCE,
BLEND_MODE_EXCLUSION,
BLEND_MODE_HARD_LIGHT,
BLEND_MODE_HUE,
BLEND_MODE_LIGHTEN,
BLEND_MODE_LUMINOSITY,
BLEND_MODE_MULTIPLY,
BLEND_MODE_NORMAL,
BLEND_MODE_OVERLAY,
BLEND_MODE_SATURATION,
BLEND_MODE_SCREEN,
BLEND_MODE_SOFT_LIGHT,
BlendMode
} from '@ui/lib/types/utils/blendModes';
export const symbolBlendMode = (blendMode?: BlendMode): BlendMode | undefined => {
if (!blendMode) return;
if (typeof blendMode !== 'string') return blendMode;
switch (blendMode) {
case 'normal':
return BLEND_MODE_NORMAL;
case 'darken':
return BLEND_MODE_DARKEN;
case 'multiply':
return BLEND_MODE_MULTIPLY;
case 'color-burn':
return BLEND_MODE_COLOR_BURN;
case 'lighten':
return BLEND_MODE_LIGHTEN;
case 'screen':
return BLEND_MODE_SCREEN;
case 'color-dodge':
return BLEND_MODE_COLOR_DODGE;
case 'overlay':
return BLEND_MODE_OVERLAY;
case 'soft-light':
return BLEND_MODE_SOFT_LIGHT;
case 'hard-light':
return BLEND_MODE_HARD_LIGHT;
case 'difference':
return BLEND_MODE_DIFFERENCE;
case 'exclusion':
return BLEND_MODE_EXCLUSION;
case 'hue':
return BLEND_MODE_HUE;
case 'saturation':
return BLEND_MODE_SATURATION;
case 'color':
return BLEND_MODE_COLOR;
case 'luminosity':
return BLEND_MODE_LUMINOSITY;
}
};

View file

@ -1,5 +1,4 @@
import { Fill } from '@ui/lib/types/utils/fill';
import { Gradient, LINEAR_TYPE, RADIAL_TYPE } from '@ui/lib/types/utils/gradient';
import { ImageColor, PartialImageColor } from '@ui/lib/types/utils/imageColor';
import { uiImages } from '@ui/parser/libraries';
@ -7,10 +6,6 @@ export const symbolFills = (fills?: Fill[]): Fill[] | undefined => {
if (!fills) return;
return fills.map(fill => {
if (fill.fillColorGradient) {
fill.fillColorGradient = symbolFillGradient(fill.fillColorGradient);
}
if (fill.fillImage) {
fill.fillImage = symbolFillImage(fill.fillImage);
}
@ -19,25 +14,6 @@ export const symbolFills = (fills?: Fill[]): Fill[] | undefined => {
});
};
const symbolFillGradient = (fillGradient: Gradient): Gradient => {
if (typeof fillGradient.type !== 'string') return fillGradient;
const { type, ...rest } = fillGradient;
switch (type) {
case 'linear':
return {
type: LINEAR_TYPE,
...rest
};
case 'radial':
return {
type: RADIAL_TYPE,
...rest
};
}
};
export const symbolFillImage = (
fillImage: ImageColor | PartialImageColor
): ImageColor | undefined => {

View file

@ -1,7 +1,6 @@
import {
Command,
PathContent,
Segment,
VECTOR_CLOSE_PATH,
VECTOR_CURVE_TO,
VECTOR_LINE_TO,
@ -9,13 +8,10 @@ import {
} from '@ui/lib/types/shapes/pathShape';
export const symbolPathContent = (content: PathContent): PathContent =>
content.map(({ command: stringCommand, ...rest }) => {
const command = symbolPathCommand(stringCommand);
content.map(segment => {
segment.command = symbolPathCommand(segment.command);
return {
command,
...rest
} as Segment;
return segment;
});
const symbolPathCommand = (command: Command): Command => {