mirror of
https://github.com/penpot/penpot-exporter-figma-plugin.git
synced 2024-12-21 21:23:06 -05:00
Refactor libraries (#189)
This commit is contained in:
parent
e8270cfd54
commit
aee78de8ac
47 changed files with 132 additions and 312 deletions
|
@ -23,7 +23,11 @@ module.exports = {
|
|||
rules: {
|
||||
'@typescript-eslint/no-unused-vars': [
|
||||
'error',
|
||||
{ ignoreRestSiblings: true, argsIgnorePattern: '^_' }
|
||||
{
|
||||
ignoreRestSiblings: true,
|
||||
argsIgnorePattern: '^_',
|
||||
destructuredArrayIgnorePattern: '^_'
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
|
7
common/map.ts
Normal file
7
common/map.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
export const toObject = <T>(map: Map<string, T>): Record<string, T> => {
|
||||
return Object.fromEntries(map.entries());
|
||||
};
|
||||
|
||||
export const toArray = <T>(map: Map<string, T>): [string, T][] => {
|
||||
return Array.from(map.entries());
|
||||
};
|
4
package-lock.json
generated
4
package-lock.json
generated
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "penpot-exporter",
|
||||
"version": "0.7.0",
|
||||
"version": "0.7.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "penpot-exporter",
|
||||
"version": "0.7.0",
|
||||
"version": "0.7.1",
|
||||
"license": "MPL2.0",
|
||||
"dependencies": {
|
||||
"@create-figma-plugin/ui": "^3.2",
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
class RemoteComponentsLibrary {
|
||||
export class RemoteComponentsLibrary {
|
||||
private components: Map<string, ComponentNode | ComponentSetNode> = new Map();
|
||||
private queue: string[] = [];
|
||||
|
||||
public register(id: string, component: ComponentNode | ComponentSetNode) {
|
||||
if (!Object.prototype.hasOwnProperty.call(this.components, id)) {
|
||||
if (!this.components.has(id)) {
|
||||
this.queue.push(id);
|
||||
}
|
||||
|
||||
|
@ -37,5 +37,3 @@ class RemoteComponentsLibrary {
|
|||
return this.components.size;
|
||||
}
|
||||
}
|
||||
|
||||
export const remoteComponents = new RemoteComponentsLibrary();
|
10
plugin-src/libraries.ts
Normal file
10
plugin-src/libraries.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
import { ComponentShape } from '@ui/lib/types/shapes/componentShape';
|
||||
|
||||
import { RemoteComponentsLibrary } from './RemoteComponents';
|
||||
|
||||
export const textStyles: Map<string, TextStyle | undefined> = new Map();
|
||||
export const paintStyles: Map<string, PaintStyle | undefined> = new Map();
|
||||
export const overrides: Map<string, NodeChangeProperty[]> = new Map();
|
||||
export const images: Map<string, Image | null> = new Map();
|
||||
export const components: Map<string, ComponentShape> = new Map();
|
||||
export const remoteComponents = new RemoteComponentsLibrary();
|
|
@ -1,23 +0,0 @@
|
|||
import { ComponentShape } from '@ui/lib/types/shapes/componentShape';
|
||||
|
||||
class Components {
|
||||
private components: Map<string, ComponentShape> = new Map();
|
||||
|
||||
public register(id: string, component: ComponentShape) {
|
||||
this.components.set(id, component);
|
||||
}
|
||||
|
||||
public get(id: string): ComponentShape | undefined {
|
||||
return this.components.get(id);
|
||||
}
|
||||
|
||||
public all(): Record<string, ComponentShape> {
|
||||
return Object.fromEntries(this.components.entries());
|
||||
}
|
||||
|
||||
public init(components: Record<string, ComponentShape>): void {
|
||||
this.components = new Map(Object.entries(components));
|
||||
}
|
||||
}
|
||||
|
||||
export const components = new Components();
|
|
@ -1,25 +0,0 @@
|
|||
class Images {
|
||||
private images: Map<string, Image | null> = new Map();
|
||||
|
||||
public register(hash: string, image: Image | null) {
|
||||
this.images.set(hash, image);
|
||||
}
|
||||
|
||||
public get(hash: string): Image | null | undefined {
|
||||
return this.images.get(hash);
|
||||
}
|
||||
|
||||
public has(hash: string): boolean {
|
||||
return this.images.has(hash);
|
||||
}
|
||||
|
||||
public all(): Record<string, Image | null> {
|
||||
return Object.fromEntries(this.images.entries());
|
||||
}
|
||||
|
||||
public init(images: Record<string, Image | null>): void {
|
||||
this.images = new Map(Object.entries(images));
|
||||
}
|
||||
}
|
||||
|
||||
export const images = new Images();
|
|
@ -1,13 +0,0 @@
|
|||
class Overrides {
|
||||
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 overrides = new Overrides();
|
|
@ -1,21 +0,0 @@
|
|||
class PaintStyles {
|
||||
private styles: Map<string, PaintStyle | undefined> = new Map();
|
||||
|
||||
public register(id: string, styles?: PaintStyle | undefined) {
|
||||
this.styles.set(id, styles);
|
||||
}
|
||||
|
||||
public get(id: string): PaintStyle | undefined {
|
||||
return this.styles.get(id);
|
||||
}
|
||||
|
||||
public has(id: string): boolean {
|
||||
return this.styles.has(id);
|
||||
}
|
||||
|
||||
public all(): Record<string, PaintStyle | undefined> {
|
||||
return Object.fromEntries(this.styles.entries());
|
||||
}
|
||||
}
|
||||
|
||||
export const paintStyles = new PaintStyles();
|
|
@ -1,21 +0,0 @@
|
|||
class TextStyles {
|
||||
private styles: Map<string, TextStyle | undefined> = new Map();
|
||||
|
||||
public register(id: string, styles?: TextStyle | undefined) {
|
||||
this.styles.set(id, styles);
|
||||
}
|
||||
|
||||
public get(id: string): TextStyle | undefined {
|
||||
return this.styles.get(id);
|
||||
}
|
||||
|
||||
public has(id: string): boolean {
|
||||
return this.styles.has(id);
|
||||
}
|
||||
|
||||
public all(): Record<string, TextStyle | undefined> {
|
||||
return Object.fromEntries(this.styles.entries());
|
||||
}
|
||||
}
|
||||
|
||||
export const textStyles = new TextStyles();
|
|
@ -1,6 +0,0 @@
|
|||
export * from './Components';
|
||||
export * from './Images';
|
||||
export * from './Overrides';
|
||||
export * from './RemoteComponents';
|
||||
export * from './PaintStyles';
|
||||
export * from './TextStyles';
|
|
@ -1,8 +1,10 @@
|
|||
import { toArray } from '@common/map';
|
||||
import { sleep } from '@common/sleep';
|
||||
|
||||
import { images as imagesLibrary } from '@plugin/libraries';
|
||||
import { sleep } from '@plugin/utils';
|
||||
|
||||
export const processImages = async (): Promise<Record<string, Uint8Array>> => {
|
||||
const imageToDownload = Object.entries(imagesLibrary.all());
|
||||
const imageToDownload = toArray(imagesLibrary);
|
||||
const images: Record<string, Uint8Array> = {};
|
||||
|
||||
if (imageToDownload.length === 0) return images;
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { sleep } from '@common/sleep';
|
||||
|
||||
import { remoteComponents } from '@plugin/libraries';
|
||||
import { transformPageNode } from '@plugin/transformers';
|
||||
import { translateRemoteChildren } from '@plugin/translators';
|
||||
import { sleep } from '@plugin/utils';
|
||||
|
||||
import { PenpotPage } from '@ui/lib/types/penpotPage';
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { toArray } from '@common/map';
|
||||
import { sleep } from '@common/sleep';
|
||||
|
||||
import { paintStyles } from '@plugin/libraries';
|
||||
import { translatePaintStyle } from '@plugin/translators/styles';
|
||||
import { sleep } from '@plugin/utils';
|
||||
|
||||
import { FillStyle } from '@ui/lib/types/utils/fill';
|
||||
|
||||
|
@ -11,12 +13,12 @@ const isPaintStyle = (style: BaseStyle): style is PaintStyle => {
|
|||
export const registerPaintStyles = async () => {
|
||||
const localPaintStyles = await figma.getLocalPaintStylesAsync();
|
||||
localPaintStyles.forEach(style => {
|
||||
paintStyles.register(style.id, style);
|
||||
paintStyles.set(style.id, style);
|
||||
});
|
||||
};
|
||||
|
||||
export const processPaintStyles = async (): Promise<Record<string, FillStyle>> => {
|
||||
const stylesToFetch = Object.entries(paintStyles.all());
|
||||
const stylesToFetch = toArray(paintStyles);
|
||||
const styles: Record<string, FillStyle> = {};
|
||||
|
||||
if (stylesToFetch.length === 0) return styles;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { toArray } from '@common/map';
|
||||
import { sleep } from '@common/sleep';
|
||||
|
||||
import { textStyles } from '@plugin/libraries';
|
||||
import { translateTextStyle } from '@plugin/translators/styles';
|
||||
import { sleep } from '@plugin/utils';
|
||||
|
||||
import { TypographyStyle } from '@ui/lib/types/shapes/textShape';
|
||||
|
||||
|
@ -11,12 +13,12 @@ const isTextStyle = (style: BaseStyle): style is TextStyle => {
|
|||
export const registerTextStyles = async () => {
|
||||
const localTextStyles = await figma.getLocalTextStylesAsync();
|
||||
localTextStyles.forEach(style => {
|
||||
textStyles.register(style.id, style);
|
||||
textStyles.set(style.id, style);
|
||||
});
|
||||
};
|
||||
|
||||
export const processTextStyles = async (): Promise<Record<string, TypographyStyle>> => {
|
||||
const stylesToFetch = Object.entries(textStyles.all());
|
||||
const stylesToFetch = toArray(textStyles);
|
||||
const styles: Record<string, TypographyStyle> = {};
|
||||
|
||||
if (stylesToFetch.length === 0) return styles;
|
||||
|
|
|
@ -19,7 +19,7 @@ import {
|
|||
import { ComponentRoot } from '@ui/types';
|
||||
|
||||
export const transformComponentNode = async (node: ComponentNode): Promise<ComponentRoot> => {
|
||||
components.register(node.id, {
|
||||
components.set(node.id, {
|
||||
type: 'component',
|
||||
name: node.name,
|
||||
path: node.parent?.type === 'COMPONENT_SET' ? node.parent.name : '',
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { toObject } from '@common/map';
|
||||
|
||||
import { components } from '@plugin/libraries';
|
||||
import {
|
||||
processImages,
|
||||
|
@ -22,7 +24,7 @@ export const transformDocumentNode = async (node: DocumentNode): Promise<PenpotD
|
|||
return {
|
||||
name: node.name,
|
||||
children,
|
||||
components: components.all(),
|
||||
components: toObject(components),
|
||||
images,
|
||||
paintStyles,
|
||||
textStyles
|
||||
|
|
|
@ -39,7 +39,7 @@ export const transformInstanceNode = async (
|
|||
registerTextVariableOverrides(node, primaryComponent);
|
||||
|
||||
if (node.overrides.length > 0) {
|
||||
node.overrides.forEach(override => overrides.register(override.id, override.overriddenFields));
|
||||
node.overrides.forEach(override => overrides.set(override.id, override.overriddenFields));
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -128,7 +128,7 @@ const registerTextVariableOverrides = (
|
|||
});
|
||||
|
||||
textNodes.forEach(textNode => {
|
||||
overrides.register(textNode.id, ['text']);
|
||||
overrides.set(textNode.id, ['text']);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
@ -48,7 +48,7 @@ export const translateFillStyleId = (
|
|||
if (fillStyleId === figma.mixed || fillStyleId === undefined) return;
|
||||
|
||||
if (!paintStyles.has(fillStyleId)) {
|
||||
paintStyles.register(fillStyleId);
|
||||
paintStyles.set(fillStyleId, undefined);
|
||||
}
|
||||
|
||||
return fillStyleId;
|
||||
|
|
|
@ -17,7 +17,7 @@ const translateImage = (imageHash: string | null): PartialImageColor | undefined
|
|||
if (!imageHash) return;
|
||||
|
||||
if (!images.has(imageHash)) {
|
||||
images.register(imageHash, figma.getImageByHash(imageHash));
|
||||
images.set(imageHash, figma.getImageByHash(imageHash));
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
@ -7,6 +7,7 @@ export const translateCustomFont = (
|
|||
fontWeight: string
|
||||
): Pick<TextTypography, 'fontId' | 'fontVariantId' | 'fontWeight'> | undefined => {
|
||||
const customFontId = getCustomFontId(fontName);
|
||||
|
||||
return {
|
||||
fontId: customFontId ? `custom-${customFontId}` : '',
|
||||
fontVariantId: translateFontVariantId(fontName, fontWeight),
|
||||
|
|
|
@ -68,7 +68,7 @@ const translateTextStyleId = (textStyleId: string | undefined): string | undefin
|
|||
if (textStyleId === undefined) return;
|
||||
|
||||
if (!textStyles.has(textStyleId)) {
|
||||
textStyles.register(textStyleId);
|
||||
textStyles.set(textStyleId, undefined);
|
||||
}
|
||||
|
||||
return textStyleId;
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { sleep } from '@common/sleep';
|
||||
|
||||
import { remoteComponents } from '@plugin/libraries';
|
||||
import { transformGroupNodeLike, transformSceneNode } from '@plugin/transformers';
|
||||
import { transformMaskFigmaIds } from '@plugin/transformers/partials';
|
||||
import { sleep } from '@plugin/utils';
|
||||
|
||||
import { PenpotNode } from '@ui/types';
|
||||
|
||||
|
|
|
@ -5,4 +5,3 @@ export * from './calculateLinearGradient';
|
|||
export * from './calculateRadialGradient';
|
||||
export * from './matrixInvert';
|
||||
export * from './rgbToHex';
|
||||
export * from './sleep';
|
||||
|
|
|
@ -11,7 +11,7 @@ const config = {
|
|||
trailingComma: 'none',
|
||||
useTabs: false,
|
||||
plugins: ['@trivago/prettier-plugin-sort-imports'],
|
||||
importOrder: ['^@plugin/(.*)$', '^@ui/(.*)$', '^[./]'],
|
||||
importOrder: ['^@common/(.*)$', '^@plugin/(.*)$', '^@ui/(.*)$', '^[./]'],
|
||||
importOrderSeparation: true,
|
||||
importOrderSortSpecifiers: true
|
||||
};
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@common/*": ["./common/*"],
|
||||
"@plugin/*": ["./plugin-src/*"],
|
||||
"@ui/*": ["./ui-src/*"]
|
||||
}
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
import { sleep } from '@plugin/utils/sleep';
|
||||
import { sleep } from '@common/sleep';
|
||||
|
||||
import { sendMessage } from '@ui/context';
|
||||
import { PenpotFile } from '@ui/lib/types/penpotFile';
|
||||
import { PenpotPage } from '@ui/lib/types/penpotPage';
|
||||
import { components, identifiers } from '@ui/parser';
|
||||
import {
|
||||
createColorsLibrary,
|
||||
createComponentsLibrary,
|
||||
createPage,
|
||||
createTextLibrary
|
||||
} from '@ui/parser/creators';
|
||||
import { components, identifiers } from '@ui/parser/libraries';
|
||||
|
||||
export const buildFile = async (file: PenpotFile, children: PenpotPage[]) => {
|
||||
let pagesBuilt = 1;
|
||||
|
||||
components.init();
|
||||
identifiers.init();
|
||||
components.clear();
|
||||
identifiers.clear();
|
||||
|
||||
sendMessage({
|
||||
type: 'PROGRESS_TOTAL_ITEMS',
|
||||
|
@ -28,7 +28,7 @@ export const buildFile = async (file: PenpotFile, children: PenpotPage[]) => {
|
|||
});
|
||||
|
||||
for (const page of children) {
|
||||
await createPage(file, page);
|
||||
createPage(file, page);
|
||||
|
||||
sendMessage({
|
||||
type: 'PROGRESS_PROCESSED_ITEMS',
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
import { sleep } from '@plugin/utils/sleep';
|
||||
import { toArray } from '@common/map';
|
||||
import { sleep } from '@common/sleep';
|
||||
|
||||
import { sendMessage } from '@ui/context';
|
||||
import { PenpotFile } from '@ui/lib/types/penpotFile';
|
||||
import { colors } from '@ui/parser/libraries';
|
||||
import { colors } from '@ui/parser';
|
||||
|
||||
export const createColorsLibrary = async (file: PenpotFile) => {
|
||||
let librariesBuilt = 1;
|
||||
const libraries = colors.all();
|
||||
const libraries = toArray(colors);
|
||||
|
||||
sendMessage({
|
||||
type: 'PROGRESS_TOTAL_ITEMS',
|
||||
|
@ -18,7 +19,7 @@ export const createColorsLibrary = async (file: PenpotFile) => {
|
|||
data: 'libraries'
|
||||
});
|
||||
|
||||
for (const library of libraries) {
|
||||
for (const [_, library] of libraries) {
|
||||
for (let index = 0; index < library.fills.length; index++) {
|
||||
file.addLibraryColor({
|
||||
...library.colors[index],
|
||||
|
|
|
@ -1,20 +1,18 @@
|
|||
import { components } from '@plugin/libraries/Components';
|
||||
|
||||
import { PenpotFile } from '@ui/lib/types/penpotFile';
|
||||
import { components as uiComponents } from '@ui/parser/libraries';
|
||||
import { componentShapes, components } from '@ui/parser';
|
||||
import { ComponentRoot } from '@ui/types';
|
||||
|
||||
import { createArtboard } from '.';
|
||||
|
||||
export const createComponent = (file: PenpotFile, { figmaId }: ComponentRoot) => {
|
||||
const component = components.get(figmaId);
|
||||
const componentShape = componentShapes.get(figmaId);
|
||||
|
||||
if (!component) {
|
||||
if (!componentShape) {
|
||||
return;
|
||||
}
|
||||
|
||||
const componentId = getComponentId(file, figmaId);
|
||||
const { type, ...shape } = component;
|
||||
const { type, ...shape } = componentShape;
|
||||
|
||||
shape.componentFile = file.getId();
|
||||
shape.componentId = componentId;
|
||||
|
@ -27,7 +25,7 @@ export const createComponent = (file: PenpotFile, { figmaId }: ComponentRoot) =>
|
|||
return;
|
||||
}
|
||||
|
||||
uiComponents.register(figmaId, {
|
||||
components.set(figmaId, {
|
||||
componentId,
|
||||
mainInstancePage: file.getCurrentPageId(),
|
||||
componentFigmaId: figmaId,
|
||||
|
@ -36,7 +34,7 @@ export const createComponent = (file: PenpotFile, { figmaId }: ComponentRoot) =>
|
|||
};
|
||||
|
||||
const getComponentId = (file: PenpotFile, figmaId: string) => {
|
||||
const uiComponent = uiComponents.get(figmaId);
|
||||
const component = components.get(figmaId);
|
||||
|
||||
return uiComponent?.componentId ?? file.newId();
|
||||
return component?.componentId ?? file.newId();
|
||||
};
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { PenpotFile } from '@ui/lib/types/penpotFile';
|
||||
import { parseFigmaId } from '@ui/parser';
|
||||
import { components } from '@ui/parser/libraries';
|
||||
import { components, parseFigmaId } from '@ui/parser';
|
||||
import { ComponentInstance } from '@ui/types';
|
||||
|
||||
import { createArtboard } from '.';
|
||||
|
@ -43,7 +42,7 @@ const createUiComponent = (file: PenpotFile, mainComponentFigmaId: string) => {
|
|||
mainInstanceId
|
||||
};
|
||||
|
||||
components.register(mainComponentFigmaId, uiComponent);
|
||||
components.set(mainComponentFigmaId, uiComponent);
|
||||
|
||||
return uiComponent;
|
||||
};
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
import { components } from '@plugin/libraries/Components';
|
||||
import { sleep } from '@plugin/utils/sleep';
|
||||
import { toArray } from '@common/map';
|
||||
import { sleep } from '@common/sleep';
|
||||
|
||||
import { sendMessage } from '@ui/context';
|
||||
import { PenpotFile } from '@ui/lib/types/penpotFile';
|
||||
import { UiComponent, componentShapes, components as uiComponents } from '@ui/parser';
|
||||
import { symbolFills, symbolStrokes } from '@ui/parser/creators/symbols';
|
||||
import { UiComponent, components as uiComponents } from '@ui/parser/libraries';
|
||||
|
||||
import { createItems } from '.';
|
||||
|
||||
export const createComponentsLibrary = async (file: PenpotFile) => {
|
||||
let componentsBuilt = 1;
|
||||
const components = uiComponents.all();
|
||||
const components = toArray(uiComponents);
|
||||
|
||||
sendMessage({
|
||||
type: 'PROGRESS_TOTAL_ITEMS',
|
||||
|
@ -22,7 +22,7 @@ export const createComponentsLibrary = async (file: PenpotFile) => {
|
|||
data: 'components'
|
||||
});
|
||||
|
||||
for (const uiComponent of components) {
|
||||
for (const [_, uiComponent] of components) {
|
||||
createComponentLibrary(file, uiComponent);
|
||||
|
||||
sendMessage({
|
||||
|
@ -34,14 +34,14 @@ export const createComponentsLibrary = async (file: PenpotFile) => {
|
|||
}
|
||||
};
|
||||
|
||||
const createComponentLibrary = async (file: PenpotFile, uiComponent: UiComponent) => {
|
||||
const component = components.get(uiComponent.componentFigmaId);
|
||||
const createComponentLibrary = (file: PenpotFile, uiComponent: UiComponent) => {
|
||||
const componentShape = componentShapes.get(uiComponent.componentFigmaId);
|
||||
|
||||
if (!component) {
|
||||
if (!componentShape) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { children = [], ...shape } = component;
|
||||
const { children = [], ...shape } = componentShape;
|
||||
|
||||
shape.fills = symbolFills(shape.fillStyleId, shape.fills);
|
||||
shape.strokes = symbolStrokes(shape.strokes);
|
||||
|
|
|
@ -1,20 +1,12 @@
|
|||
// @TODO: Direct import on purpose, to avoid problems with the tsc linting
|
||||
import { sleep } from '@plugin/utils/sleep';
|
||||
|
||||
import { PenpotFile } from '@ui/lib/types/penpotFile';
|
||||
import { PenpotPage } from '@ui/lib/types/penpotPage';
|
||||
|
||||
import { createItems } from '.';
|
||||
|
||||
export const createPage = async (
|
||||
file: PenpotFile,
|
||||
{ name, options, children = [] }: PenpotPage
|
||||
) => {
|
||||
export const createPage = (file: PenpotFile, { name, options, children = [] }: PenpotPage) => {
|
||||
file.addPage(name, options);
|
||||
|
||||
createItems(file, children);
|
||||
|
||||
await sleep(0);
|
||||
|
||||
file.closePage();
|
||||
};
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { PenpotFile } from '@ui/lib/types/penpotFile';
|
||||
import { Paragraph, TextContent, TextNode, TextShape } from '@ui/lib/types/shapes/textShape';
|
||||
import { parseFigmaId } from '@ui/parser';
|
||||
import { parseFigmaId, typographies } from '@ui/parser';
|
||||
import { symbolFills, symbolStrokes } from '@ui/parser/creators/symbols';
|
||||
import { typographies } from '@ui/parser/libraries';
|
||||
|
||||
export const createText = (
|
||||
file: PenpotFile,
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
import { sleep } from '@plugin/utils/sleep';
|
||||
import { toArray } from '@common/map';
|
||||
import { sleep } from '@common/sleep';
|
||||
|
||||
import { sendMessage } from '@ui/context';
|
||||
import { PenpotFile } from '@ui/lib/types/penpotFile';
|
||||
import { typographies } from '@ui/parser/libraries';
|
||||
import { typographies } from '@ui/parser';
|
||||
|
||||
export const createTextLibrary = async (file: PenpotFile) => {
|
||||
let librariesBuilt = 1;
|
||||
const libraries = typographies.all();
|
||||
const libraries = toArray(typographies);
|
||||
|
||||
sendMessage({
|
||||
type: 'PROGRESS_TOTAL_ITEMS',
|
||||
|
@ -18,7 +19,7 @@ export const createTextLibrary = async (file: PenpotFile) => {
|
|||
data: 'typoLibraries'
|
||||
});
|
||||
|
||||
for (const library of libraries) {
|
||||
for (const [_, library] of libraries) {
|
||||
file.addLibraryTypography({
|
||||
...library.typography,
|
||||
fontId: library.textStyle.fontId,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Fill } from '@ui/lib/types/utils/fill';
|
||||
import { ImageColor, PartialImageColor } from '@ui/lib/types/utils/imageColor';
|
||||
import { colors, images } from '@ui/parser/libraries';
|
||||
import { colors, images } from '@ui/parser';
|
||||
|
||||
export const symbolFills = (fillStyleId?: string, fills?: Fill[]): Fill[] | undefined => {
|
||||
const nodeFills = fillStyleId ? colors.get(fillStyleId)?.fills : fills;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
export * from './libraries';
|
||||
export * from './parse';
|
||||
export * from './parseImage';
|
||||
export * from './parseFigmaId';
|
||||
|
|
24
ui-src/parser/libraries.ts
Normal file
24
ui-src/parser/libraries.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
import { ComponentShape } from '@ui/lib/types/shapes/componentShape';
|
||||
import { TypographyStyle } from '@ui/lib/types/shapes/textShape';
|
||||
import { FillStyle } from '@ui/lib/types/utils/fill';
|
||||
import { ImageColor } from '@ui/lib/types/utils/imageColor';
|
||||
import { Uuid } from '@ui/lib/types/utils/uuid';
|
||||
|
||||
export type UiComponent = {
|
||||
componentId: Uuid;
|
||||
mainInstancePage?: Uuid;
|
||||
mainInstanceId: Uuid;
|
||||
componentFigmaId: string;
|
||||
};
|
||||
|
||||
export const init = <T>(records: Record<string, T>, map: Map<string, T>) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
map = new Map(Object.entries(records));
|
||||
};
|
||||
|
||||
export const typographies: Map<string, TypographyStyle> = new Map();
|
||||
export const images: Map<string, ImageColor> = new Map();
|
||||
export const identifiers: Map<string, Uuid> = new Map();
|
||||
export const components: Map<string, UiComponent> = new Map();
|
||||
export const componentShapes: Map<string, ComponentShape> = new Map();
|
||||
export const colors: Map<string, FillStyle> = new Map();
|
|
@ -1,19 +0,0 @@
|
|||
import { FillStyle } from '@ui/lib/types/utils/fill';
|
||||
|
||||
class Colors {
|
||||
private libraries: Map<string, FillStyle> = new Map();
|
||||
|
||||
public register(id: string, fillStyle: FillStyle) {
|
||||
this.libraries.set(id, fillStyle);
|
||||
}
|
||||
|
||||
public get(id: string): FillStyle | undefined {
|
||||
return this.libraries.get(id);
|
||||
}
|
||||
|
||||
public all(): FillStyle[] {
|
||||
return Array.from(this.libraries.values());
|
||||
}
|
||||
}
|
||||
|
||||
export const colors = new Colors();
|
|
@ -1,30 +0,0 @@
|
|||
import { Uuid } from '@ui/lib/types/utils/uuid';
|
||||
|
||||
export type UiComponent = {
|
||||
componentId: Uuid;
|
||||
mainInstancePage?: Uuid;
|
||||
mainInstanceId: Uuid;
|
||||
componentFigmaId: string;
|
||||
};
|
||||
|
||||
class Components {
|
||||
private components: Map<string, UiComponent> = new Map();
|
||||
|
||||
public register(id: string, component: UiComponent) {
|
||||
this.components.set(id, component);
|
||||
}
|
||||
|
||||
public get(id: string): UiComponent | undefined {
|
||||
return this.components.get(id);
|
||||
}
|
||||
|
||||
public all(): UiComponent[] {
|
||||
return Array.from(this.components.values());
|
||||
}
|
||||
|
||||
public init() {
|
||||
this.components.clear();
|
||||
}
|
||||
}
|
||||
|
||||
export const components = new Components();
|
|
@ -1,19 +0,0 @@
|
|||
import { Uuid } from '@ui/lib/types/utils/uuid';
|
||||
|
||||
class Identifiers {
|
||||
private idMap: Map<string, Uuid> = new Map();
|
||||
|
||||
public init() {
|
||||
this.idMap.clear();
|
||||
}
|
||||
|
||||
public get(figmaId: string): Uuid | undefined {
|
||||
return this.idMap.get(figmaId);
|
||||
}
|
||||
|
||||
public register(figmaId: string, id: Uuid) {
|
||||
this.idMap.set(figmaId, id);
|
||||
}
|
||||
}
|
||||
|
||||
export const identifiers = new Identifiers();
|
|
@ -1,23 +0,0 @@
|
|||
import { ImageColor } from '@ui/lib/types/utils/imageColor';
|
||||
|
||||
class Images {
|
||||
private images: Map<string, ImageColor> = new Map();
|
||||
|
||||
public register(id: string, image: ImageColor) {
|
||||
this.images.set(id, image);
|
||||
}
|
||||
|
||||
public get(id: string): ImageColor | undefined {
|
||||
return this.images.get(id);
|
||||
}
|
||||
|
||||
public all(): ImageColor[] {
|
||||
return Array.from(this.images.values());
|
||||
}
|
||||
|
||||
public init() {
|
||||
this.images.clear();
|
||||
}
|
||||
}
|
||||
|
||||
export const images = new Images();
|
|
@ -1,19 +0,0 @@
|
|||
import { TypographyStyle } from '@ui/lib/types/shapes/textShape';
|
||||
|
||||
class Typographies {
|
||||
private libraries: Map<string, TypographyStyle> = new Map();
|
||||
|
||||
public register(id: string, textStyle: TypographyStyle) {
|
||||
this.libraries.set(id, textStyle);
|
||||
}
|
||||
|
||||
public get(id: string): TypographyStyle | undefined {
|
||||
return this.libraries.get(id);
|
||||
}
|
||||
|
||||
public all(): TypographyStyle[] {
|
||||
return Array.from(this.libraries.values());
|
||||
}
|
||||
}
|
||||
|
||||
export const typographies = new Typographies();
|
|
@ -1,5 +0,0 @@
|
|||
export * from './Identifiers';
|
||||
export * from './Colors';
|
||||
export * from './Components';
|
||||
export * from './Images';
|
||||
export * from './Typographies';
|
|
@ -1,20 +1,18 @@
|
|||
import { components as componentsLibrary } from '@plugin/libraries/Components';
|
||||
// @TODO: Direct import on purpose, to avoid problems with the tsc linting
|
||||
import { sleep } from '@plugin/utils/sleep';
|
||||
import { sleep } from '@common/sleep';
|
||||
|
||||
import { sendMessage } from '@ui/context';
|
||||
import { createFile } from '@ui/lib/penpot';
|
||||
import { PenpotFile } from '@ui/lib/types/penpotFile';
|
||||
import { TypographyStyle } from '@ui/lib/types/shapes/textShape';
|
||||
import { FillStyle } from '@ui/lib/types/utils/fill';
|
||||
import { colors, componentShapes, images, init, typographies } from '@ui/parser';
|
||||
import { buildFile } from '@ui/parser/creators';
|
||||
import { colors, typographies, images as uiImages } from '@ui/parser/libraries';
|
||||
import { PenpotDocument } from '@ui/types';
|
||||
|
||||
import { parseImage } from '.';
|
||||
|
||||
const optimizeImages = async (images: Record<string, Uint8Array>) => {
|
||||
const imagesToOptimize = Object.entries(images);
|
||||
const optimizeImages = async (binaryImages: Record<string, Uint8Array>) => {
|
||||
const imagesToOptimize = Object.entries(binaryImages);
|
||||
|
||||
if (imagesToOptimize.length === 0) return;
|
||||
|
||||
|
@ -32,7 +30,7 @@ const optimizeImages = async (images: Record<string, Uint8Array>) => {
|
|||
|
||||
for (const [key, bytes] of imagesToOptimize) {
|
||||
if (bytes) {
|
||||
uiImages.register(key, await parseImage(bytes));
|
||||
images.set(key, await parseImage(bytes));
|
||||
}
|
||||
|
||||
sendMessage({
|
||||
|
@ -70,7 +68,7 @@ const prepareTypographyLibraries = async (
|
|||
style.textStyle.typographyRefFile = file.getId();
|
||||
style.typography.id = typographyId;
|
||||
|
||||
typographies.register(key, style);
|
||||
typographies.set(key, style);
|
||||
|
||||
sendMessage({
|
||||
type: 'PROGRESS_PROCESSED_ITEMS',
|
||||
|
@ -107,7 +105,7 @@ const prepareColorLibraries = async (file: PenpotFile, styles: Record<string, Fi
|
|||
fillStyle.colors[index].refFile = file.getId();
|
||||
}
|
||||
|
||||
colors.register(key, fillStyle);
|
||||
colors.set(key, fillStyle);
|
||||
|
||||
sendMessage({
|
||||
type: 'PROGRESS_PROCESSED_ITEMS',
|
||||
|
@ -126,7 +124,7 @@ export const parse = async ({
|
|||
paintStyles,
|
||||
textStyles
|
||||
}: PenpotDocument) => {
|
||||
componentsLibrary.init(components);
|
||||
init(components, componentShapes);
|
||||
|
||||
const file = createFile(name);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { PenpotFile } from '@ui/lib/types/penpotFile';
|
||||
import { Uuid } from '@ui/lib/types/utils/uuid';
|
||||
import { identifiers } from '@ui/parser/libraries';
|
||||
import { identifiers } from '@ui/parser';
|
||||
|
||||
export const parseFigmaId = (
|
||||
file: PenpotFile,
|
||||
|
@ -8,19 +8,20 @@ export const parseFigmaId = (
|
|||
shapeRef: boolean = false
|
||||
): Uuid | undefined => {
|
||||
if (!figmaId) {
|
||||
if (shapeRef) {
|
||||
return;
|
||||
}
|
||||
if (shapeRef) return;
|
||||
|
||||
return file.newId();
|
||||
}
|
||||
|
||||
const id = identifiers.get(figmaId);
|
||||
|
||||
if (id) {
|
||||
return id;
|
||||
}
|
||||
|
||||
const newId = file.newId();
|
||||
identifiers.register(figmaId, newId);
|
||||
|
||||
identifiers.set(figmaId, newId);
|
||||
|
||||
return newId;
|
||||
};
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"useDefineForClassFields": true,
|
||||
"lib": ["DOM", "DOM.Iterable", "ESNext"],
|
||||
"paths": {
|
||||
"@plugin/*": ["./plugin-src/*"],
|
||||
"@common/*": ["./common/*"],
|
||||
"@ui/*": ["./ui-src/*"],
|
||||
"react": ["./node_modules/preact/compat/"],
|
||||
"react-dom": ["./node_modules/preact/compat/"],
|
||||
|
|
Loading…
Reference in a new issue