mirror of
https://github.com/penpot/penpot-exporter-figma-plugin.git
synced 2024-12-22 05:33:02 -05:00
Refactor (#188)
* refactor * fixes * rename libraries * refactor libraries * fixes
This commit is contained in:
parent
d3c144e5e9
commit
e8270cfd54
41 changed files with 373 additions and 328 deletions
|
@ -1,21 +0,0 @@
|
||||||
class ImageLibrary {
|
|
||||||
private images: Record<string, Image | null> = {};
|
|
||||||
|
|
||||||
public register(hash: string, image: Image | null) {
|
|
||||||
this.images[hash] = image;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get(hash: string): Image | null | undefined {
|
|
||||||
return this.images[hash];
|
|
||||||
}
|
|
||||||
|
|
||||||
public all(): Record<string, Image | null> {
|
|
||||||
return this.images;
|
|
||||||
}
|
|
||||||
|
|
||||||
public init(images: Record<string, Image | null>): void {
|
|
||||||
this.images = images;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const imagesLibrary = new ImageLibrary();
|
|
|
@ -1,23 +1,23 @@
|
||||||
import { ComponentShape } from '@ui/lib/types/shapes/componentShape';
|
import { ComponentShape } from '@ui/lib/types/shapes/componentShape';
|
||||||
|
|
||||||
class ComponentLibrary {
|
class Components {
|
||||||
private components: Record<string, ComponentShape> = {};
|
private components: Map<string, ComponentShape> = new Map();
|
||||||
|
|
||||||
public register(id: string, component: ComponentShape) {
|
public register(id: string, component: ComponentShape) {
|
||||||
this.components[id] = component;
|
this.components.set(id, component);
|
||||||
}
|
}
|
||||||
|
|
||||||
public get(id: string): ComponentShape | undefined {
|
public get(id: string): ComponentShape | undefined {
|
||||||
return this.components[id];
|
return this.components.get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public all(): Record<string, ComponentShape> {
|
public all(): Record<string, ComponentShape> {
|
||||||
return this.components;
|
return Object.fromEntries(this.components.entries());
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(components: Record<string, ComponentShape>): void {
|
public init(components: Record<string, ComponentShape>): void {
|
||||||
this.components = components;
|
this.components = new Map(Object.entries(components));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const componentsLibrary = new ComponentLibrary();
|
export const components = new Components();
|
25
plugin-src/libraries/Images.ts
Normal file
25
plugin-src/libraries/Images.ts
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
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,4 +1,4 @@
|
||||||
class OverridesLibrary {
|
class Overrides {
|
||||||
private overrides: Map<string, NodeChangeProperty[]> = new Map();
|
private overrides: Map<string, NodeChangeProperty[]> = new Map();
|
||||||
|
|
||||||
public register(nodeId: string, overrides: NodeChangeProperty[]): void {
|
public register(nodeId: string, overrides: NodeChangeProperty[]): void {
|
||||||
|
@ -10,4 +10,4 @@ class OverridesLibrary {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const overridesLibrary = new OverridesLibrary();
|
export const overrides = new Overrides();
|
|
@ -1,4 +1,4 @@
|
||||||
class StyleLibrary {
|
class PaintStyles {
|
||||||
private styles: Map<string, PaintStyle | undefined> = new Map();
|
private styles: Map<string, PaintStyle | undefined> = new Map();
|
||||||
|
|
||||||
public register(id: string, styles?: PaintStyle | undefined) {
|
public register(id: string, styles?: PaintStyle | undefined) {
|
||||||
|
@ -18,4 +18,4 @@ class StyleLibrary {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const styleLibrary = new StyleLibrary();
|
export const paintStyles = new PaintStyles();
|
|
@ -1,5 +1,5 @@
|
||||||
class RemoteComponentsLibrary {
|
class RemoteComponentsLibrary {
|
||||||
private components: Record<string, ComponentNode | ComponentSetNode> = {};
|
private components: Map<string, ComponentNode | ComponentSetNode> = new Map();
|
||||||
private queue: string[] = [];
|
private queue: string[] = [];
|
||||||
|
|
||||||
public register(id: string, component: ComponentNode | ComponentSetNode) {
|
public register(id: string, component: ComponentNode | ComponentSetNode) {
|
||||||
|
@ -7,11 +7,15 @@ class RemoteComponentsLibrary {
|
||||||
this.queue.push(id);
|
this.queue.push(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.components[id] = component;
|
this.components.set(id, component);
|
||||||
}
|
}
|
||||||
|
|
||||||
public get(id: string): ComponentNode | ComponentSetNode | undefined {
|
public get(id: string): ComponentNode | ComponentSetNode | undefined {
|
||||||
return this.components[id];
|
return this.components.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public has(id: string): boolean {
|
||||||
|
return this.components.has(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public next(): ComponentNode | ComponentSetNode {
|
public next(): ComponentNode | ComponentSetNode {
|
||||||
|
@ -19,7 +23,10 @@ class RemoteComponentsLibrary {
|
||||||
|
|
||||||
if (!lastKey) throw new Error('No components to pop');
|
if (!lastKey) throw new Error('No components to pop');
|
||||||
|
|
||||||
return this.components[lastKey];
|
const component = this.components.get(lastKey);
|
||||||
|
if (!component) throw new Error('Component not found');
|
||||||
|
|
||||||
|
return component;
|
||||||
}
|
}
|
||||||
|
|
||||||
public remaining(): number {
|
public remaining(): number {
|
||||||
|
@ -27,8 +34,8 @@ class RemoteComponentsLibrary {
|
||||||
}
|
}
|
||||||
|
|
||||||
public total(): number {
|
public total(): number {
|
||||||
return Object.keys(this.components).length;
|
return this.components.size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const remoteComponentLibrary = new RemoteComponentsLibrary();
|
export const remoteComponents = new RemoteComponentsLibrary();
|
|
@ -1,4 +1,4 @@
|
||||||
class TextLibrary {
|
class TextStyles {
|
||||||
private styles: Map<string, TextStyle | undefined> = new Map();
|
private styles: Map<string, TextStyle | undefined> = new Map();
|
||||||
|
|
||||||
public register(id: string, styles?: TextStyle | undefined) {
|
public register(id: string, styles?: TextStyle | undefined) {
|
||||||
|
@ -18,4 +18,4 @@ class TextLibrary {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const textLibrary = new TextLibrary();
|
export const textStyles = new TextStyles();
|
6
plugin-src/libraries/index.ts
Normal file
6
plugin-src/libraries/index.ts
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
export * from './Components';
|
||||||
|
export * from './Images';
|
||||||
|
export * from './Overrides';
|
||||||
|
export * from './RemoteComponents';
|
||||||
|
export * from './PaintStyles';
|
||||||
|
export * from './TextStyles';
|
4
plugin-src/processors/index.ts
Normal file
4
plugin-src/processors/index.ts
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
export * from './processImages';
|
||||||
|
export * from './processPaintStyles';
|
||||||
|
export * from './processTextStyles';
|
||||||
|
export * from './processPages';
|
40
plugin-src/processors/processImages.ts
Normal file
40
plugin-src/processors/processImages.ts
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
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 images: Record<string, Uint8Array> = {};
|
||||||
|
|
||||||
|
if (imageToDownload.length === 0) return images;
|
||||||
|
|
||||||
|
let currentImage = 1;
|
||||||
|
|
||||||
|
figma.ui.postMessage({
|
||||||
|
type: 'PROGRESS_TOTAL_ITEMS',
|
||||||
|
data: imageToDownload.length
|
||||||
|
});
|
||||||
|
|
||||||
|
figma.ui.postMessage({
|
||||||
|
type: 'PROGRESS_STEP',
|
||||||
|
data: 'images'
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const [key, image] of imageToDownload) {
|
||||||
|
const bytes = await image?.getBytesAsync();
|
||||||
|
|
||||||
|
if (bytes) {
|
||||||
|
images[key] = bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
figma.ui.postMessage({
|
||||||
|
type: 'PROGRESS_PROCESSED_ITEMS',
|
||||||
|
data: currentImage++
|
||||||
|
});
|
||||||
|
|
||||||
|
await sleep(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
await sleep(20);
|
||||||
|
|
||||||
|
return images;
|
||||||
|
};
|
50
plugin-src/processors/processPages.ts
Normal file
50
plugin-src/processors/processPages.ts
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
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';
|
||||||
|
|
||||||
|
export const processPages = async (node: DocumentNode): Promise<PenpotPage[]> => {
|
||||||
|
const children = await processLocalDocument(node);
|
||||||
|
const remoteComponents = await processRemoteComponents();
|
||||||
|
if (remoteComponents) {
|
||||||
|
children.push(remoteComponents);
|
||||||
|
}
|
||||||
|
|
||||||
|
return children;
|
||||||
|
};
|
||||||
|
|
||||||
|
const processRemoteComponents = async (): Promise<PenpotPage | undefined> => {
|
||||||
|
if (remoteComponents.remaining() > 0) {
|
||||||
|
return {
|
||||||
|
name: 'External Components',
|
||||||
|
children: await translateRemoteChildren()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const processLocalDocument = async (node: DocumentNode): Promise<PenpotPage[]> => {
|
||||||
|
const children = [];
|
||||||
|
let currentPage = 1;
|
||||||
|
|
||||||
|
figma.ui.postMessage({
|
||||||
|
type: 'PROGRESS_TOTAL_ITEMS',
|
||||||
|
data: node.children.length
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const page of node.children) {
|
||||||
|
await page.loadAsync();
|
||||||
|
|
||||||
|
children.push(await transformPageNode(page));
|
||||||
|
|
||||||
|
figma.ui.postMessage({
|
||||||
|
type: 'PROGRESS_PROCESSED_ITEMS',
|
||||||
|
data: currentPage++
|
||||||
|
});
|
||||||
|
|
||||||
|
await sleep(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return children;
|
||||||
|
};
|
53
plugin-src/processors/processPaintStyles.ts
Normal file
53
plugin-src/processors/processPaintStyles.ts
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
import { paintStyles } from '@plugin/libraries';
|
||||||
|
import { translatePaintStyle } from '@plugin/translators/styles';
|
||||||
|
import { sleep } from '@plugin/utils';
|
||||||
|
|
||||||
|
import { FillStyle } from '@ui/lib/types/utils/fill';
|
||||||
|
|
||||||
|
const isPaintStyle = (style: BaseStyle): style is PaintStyle => {
|
||||||
|
return style.type === 'PAINT';
|
||||||
|
};
|
||||||
|
|
||||||
|
export const registerPaintStyles = async () => {
|
||||||
|
const localPaintStyles = await figma.getLocalPaintStylesAsync();
|
||||||
|
localPaintStyles.forEach(style => {
|
||||||
|
paintStyles.register(style.id, style);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const processPaintStyles = async (): Promise<Record<string, FillStyle>> => {
|
||||||
|
const stylesToFetch = Object.entries(paintStyles.all());
|
||||||
|
const styles: Record<string, FillStyle> = {};
|
||||||
|
|
||||||
|
if (stylesToFetch.length === 0) return styles;
|
||||||
|
|
||||||
|
let currentStyle = 1;
|
||||||
|
|
||||||
|
figma.ui.postMessage({
|
||||||
|
type: 'PROGRESS_TOTAL_ITEMS',
|
||||||
|
data: stylesToFetch.length
|
||||||
|
});
|
||||||
|
|
||||||
|
figma.ui.postMessage({
|
||||||
|
type: 'PROGRESS_STEP',
|
||||||
|
data: 'fills'
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const [styleId, paintStyle] of stylesToFetch) {
|
||||||
|
const figmaStyle = paintStyle ?? (await figma.getStyleByIdAsync(styleId));
|
||||||
|
if (figmaStyle && isPaintStyle(figmaStyle)) {
|
||||||
|
styles[styleId] = translatePaintStyle(figmaStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
figma.ui.postMessage({
|
||||||
|
type: 'PROGRESS_PROCESSED_ITEMS',
|
||||||
|
data: currentStyle++
|
||||||
|
});
|
||||||
|
|
||||||
|
await sleep(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
await sleep(20);
|
||||||
|
|
||||||
|
return styles;
|
||||||
|
};
|
53
plugin-src/processors/processTextStyles.ts
Normal file
53
plugin-src/processors/processTextStyles.ts
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
import { textStyles } from '@plugin/libraries';
|
||||||
|
import { translateTextStyle } from '@plugin/translators/styles';
|
||||||
|
import { sleep } from '@plugin/utils';
|
||||||
|
|
||||||
|
import { TypographyStyle } from '@ui/lib/types/shapes/textShape';
|
||||||
|
|
||||||
|
const isTextStyle = (style: BaseStyle): style is TextStyle => {
|
||||||
|
return style.type === 'TEXT';
|
||||||
|
};
|
||||||
|
|
||||||
|
export const registerTextStyles = async () => {
|
||||||
|
const localTextStyles = await figma.getLocalTextStylesAsync();
|
||||||
|
localTextStyles.forEach(style => {
|
||||||
|
textStyles.register(style.id, style);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const processTextStyles = async (): Promise<Record<string, TypographyStyle>> => {
|
||||||
|
const stylesToFetch = Object.entries(textStyles.all());
|
||||||
|
const styles: Record<string, TypographyStyle> = {};
|
||||||
|
|
||||||
|
if (stylesToFetch.length === 0) return styles;
|
||||||
|
|
||||||
|
let currentStyle = 1;
|
||||||
|
|
||||||
|
figma.ui.postMessage({
|
||||||
|
type: 'PROGRESS_TOTAL_ITEMS',
|
||||||
|
data: stylesToFetch.length
|
||||||
|
});
|
||||||
|
|
||||||
|
figma.ui.postMessage({
|
||||||
|
type: 'PROGRESS_STEP',
|
||||||
|
data: 'typographies'
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const [styleId, style] of stylesToFetch) {
|
||||||
|
const figmaStyle = style ?? (await figma.getStyleByIdAsync(styleId));
|
||||||
|
if (figmaStyle && isTextStyle(figmaStyle)) {
|
||||||
|
styles[styleId] = translateTextStyle(figmaStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
figma.ui.postMessage({
|
||||||
|
type: 'PROGRESS_PROCESSED_ITEMS',
|
||||||
|
data: currentStyle++
|
||||||
|
});
|
||||||
|
|
||||||
|
await sleep(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
await sleep(20);
|
||||||
|
|
||||||
|
return styles;
|
||||||
|
};
|
|
@ -1,4 +1,4 @@
|
||||||
import { overridesLibrary } from '@plugin/OverridesLibrary';
|
import { overrides as overridesLibrary } from '@plugin/libraries';
|
||||||
import { syncAttributes } from '@plugin/utils/syncAttributes';
|
import { syncAttributes } from '@plugin/utils/syncAttributes';
|
||||||
|
|
||||||
import { SyncGroups } from '@ui/lib/types/utils/syncGroups';
|
import { SyncGroups } from '@ui/lib/types/utils/syncGroups';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { componentsLibrary } from '@plugin/ComponentLibrary';
|
import { components } from '@plugin/libraries';
|
||||||
import {
|
import {
|
||||||
transformAutoLayout,
|
transformAutoLayout,
|
||||||
transformBlend,
|
transformBlend,
|
||||||
|
@ -19,7 +19,7 @@ import {
|
||||||
import { ComponentRoot } from '@ui/types';
|
import { ComponentRoot } from '@ui/types';
|
||||||
|
|
||||||
export const transformComponentNode = async (node: ComponentNode): Promise<ComponentRoot> => {
|
export const transformComponentNode = async (node: ComponentNode): Promise<ComponentRoot> => {
|
||||||
componentsLibrary.register(node.id, {
|
components.register(node.id, {
|
||||||
type: 'component',
|
type: 'component',
|
||||||
name: node.name,
|
name: node.name,
|
||||||
path: node.parent?.type === 'COMPONENT_SET' ? node.parent.name : '',
|
path: node.parent?.type === 'COMPONENT_SET' ? node.parent.name : '',
|
||||||
|
|
|
@ -1,196 +1,30 @@
|
||||||
import { componentsLibrary } from '@plugin/ComponentLibrary';
|
import { components } from '@plugin/libraries';
|
||||||
import { imagesLibrary } from '@plugin/ImageLibrary';
|
import {
|
||||||
import { remoteComponentLibrary } from '@plugin/RemoteComponentLibrary';
|
processImages,
|
||||||
import { styleLibrary } from '@plugin/StyleLibrary';
|
processPages,
|
||||||
import { textLibrary } from '@plugin/TextLibrary';
|
processPaintStyles,
|
||||||
import { translateRemoteChildren } from '@plugin/translators';
|
processTextStyles,
|
||||||
import { translatePaintStyle, translateTextStyle } from '@plugin/translators/styles';
|
registerPaintStyles,
|
||||||
import { sleep } from '@plugin/utils';
|
registerTextStyles
|
||||||
|
} from '@plugin/processors';
|
||||||
|
|
||||||
import { PenpotPage } from '@ui/lib/types/penpotPage';
|
|
||||||
import { TypographyStyle } from '@ui/lib/types/shapes/textShape';
|
|
||||||
import { FillStyle } from '@ui/lib/types/utils/fill';
|
|
||||||
import { PenpotDocument } from '@ui/types';
|
import { PenpotDocument } from '@ui/types';
|
||||||
|
|
||||||
import { transformPageNode } from '.';
|
|
||||||
|
|
||||||
const isPaintStyle = (style: BaseStyle): style is PaintStyle => {
|
|
||||||
return style.type === 'PAINT';
|
|
||||||
};
|
|
||||||
|
|
||||||
const isTextStyle = (style: BaseStyle): style is TextStyle => {
|
|
||||||
return style.type === 'TEXT';
|
|
||||||
};
|
|
||||||
|
|
||||||
const downloadImages = async (): Promise<Record<string, Uint8Array>> => {
|
|
||||||
const imageToDownload = Object.entries(imagesLibrary.all());
|
|
||||||
const images: Record<string, Uint8Array> = {};
|
|
||||||
|
|
||||||
if (imageToDownload.length === 0) return images;
|
|
||||||
|
|
||||||
let currentImage = 1;
|
|
||||||
|
|
||||||
figma.ui.postMessage({
|
|
||||||
type: 'PROGRESS_TOTAL_ITEMS',
|
|
||||||
data: imageToDownload.length
|
|
||||||
});
|
|
||||||
|
|
||||||
figma.ui.postMessage({
|
|
||||||
type: 'PROGRESS_STEP',
|
|
||||||
data: 'images'
|
|
||||||
});
|
|
||||||
|
|
||||||
for (const [key, image] of imageToDownload) {
|
|
||||||
const bytes = await image?.getBytesAsync();
|
|
||||||
|
|
||||||
if (bytes) {
|
|
||||||
images[key] = bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
figma.ui.postMessage({
|
|
||||||
type: 'PROGRESS_PROCESSED_ITEMS',
|
|
||||||
data: currentImage++
|
|
||||||
});
|
|
||||||
|
|
||||||
await sleep(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
await sleep(20);
|
|
||||||
|
|
||||||
return images;
|
|
||||||
};
|
|
||||||
|
|
||||||
const getFillStyles = async (): Promise<Record<string, FillStyle>> => {
|
|
||||||
const stylesToFetch = Object.entries(styleLibrary.all());
|
|
||||||
const styles: Record<string, FillStyle> = {};
|
|
||||||
|
|
||||||
if (stylesToFetch.length === 0) return styles;
|
|
||||||
|
|
||||||
let currentStyle = 1;
|
|
||||||
|
|
||||||
figma.ui.postMessage({
|
|
||||||
type: 'PROGRESS_TOTAL_ITEMS',
|
|
||||||
data: stylesToFetch.length
|
|
||||||
});
|
|
||||||
|
|
||||||
figma.ui.postMessage({
|
|
||||||
type: 'PROGRESS_STEP',
|
|
||||||
data: 'fills'
|
|
||||||
});
|
|
||||||
|
|
||||||
for (const [styleId, paintStyle] of stylesToFetch) {
|
|
||||||
const figmaStyle = paintStyle ?? (await figma.getStyleByIdAsync(styleId));
|
|
||||||
if (figmaStyle && isPaintStyle(figmaStyle)) {
|
|
||||||
styles[styleId] = translatePaintStyle(figmaStyle);
|
|
||||||
}
|
|
||||||
|
|
||||||
figma.ui.postMessage({
|
|
||||||
type: 'PROGRESS_PROCESSED_ITEMS',
|
|
||||||
data: currentStyle++
|
|
||||||
});
|
|
||||||
|
|
||||||
await sleep(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
await sleep(20);
|
|
||||||
|
|
||||||
return styles;
|
|
||||||
};
|
|
||||||
|
|
||||||
const getTextStyles = async (): Promise<Record<string, TypographyStyle>> => {
|
|
||||||
const stylesToFetch = Object.entries(textLibrary.all());
|
|
||||||
const styles: Record<string, TypographyStyle> = {};
|
|
||||||
|
|
||||||
if (stylesToFetch.length === 0) return styles;
|
|
||||||
|
|
||||||
let currentStyle = 1;
|
|
||||||
|
|
||||||
figma.ui.postMessage({
|
|
||||||
type: 'PROGRESS_TOTAL_ITEMS',
|
|
||||||
data: stylesToFetch.length
|
|
||||||
});
|
|
||||||
|
|
||||||
figma.ui.postMessage({
|
|
||||||
type: 'PROGRESS_STEP',
|
|
||||||
data: 'typographies'
|
|
||||||
});
|
|
||||||
|
|
||||||
for (const [styleId, style] of stylesToFetch) {
|
|
||||||
const figmaStyle = style ?? (await figma.getStyleByIdAsync(styleId));
|
|
||||||
if (figmaStyle && isTextStyle(figmaStyle)) {
|
|
||||||
styles[styleId] = translateTextStyle(figmaStyle);
|
|
||||||
}
|
|
||||||
|
|
||||||
figma.ui.postMessage({
|
|
||||||
type: 'PROGRESS_PROCESSED_ITEMS',
|
|
||||||
data: currentStyle++
|
|
||||||
});
|
|
||||||
|
|
||||||
await sleep(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
await sleep(20);
|
|
||||||
|
|
||||||
return styles;
|
|
||||||
};
|
|
||||||
|
|
||||||
const processPages = async (node: DocumentNode): Promise<PenpotPage[]> => {
|
|
||||||
const children = [];
|
|
||||||
let currentPage = 1;
|
|
||||||
|
|
||||||
figma.ui.postMessage({
|
|
||||||
type: 'PROGRESS_TOTAL_ITEMS',
|
|
||||||
data: node.children.length
|
|
||||||
});
|
|
||||||
|
|
||||||
for (const page of node.children) {
|
|
||||||
await page.loadAsync();
|
|
||||||
|
|
||||||
children.push(await transformPageNode(page));
|
|
||||||
|
|
||||||
figma.ui.postMessage({
|
|
||||||
type: 'PROGRESS_PROCESSED_ITEMS',
|
|
||||||
data: currentPage++
|
|
||||||
});
|
|
||||||
|
|
||||||
await sleep(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return children;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const transformDocumentNode = async (node: DocumentNode): Promise<PenpotDocument> => {
|
export const transformDocumentNode = async (node: DocumentNode): Promise<PenpotDocument> => {
|
||||||
const localPaintStyles = await figma.getLocalPaintStylesAsync();
|
await registerPaintStyles();
|
||||||
localPaintStyles.forEach(style => {
|
await registerTextStyles();
|
||||||
styleLibrary.register(style.id, style);
|
|
||||||
});
|
|
||||||
|
|
||||||
const localTextStyles = await figma.getLocalTextStylesAsync();
|
|
||||||
localTextStyles.forEach(style => {
|
|
||||||
textLibrary.register(style.id, style);
|
|
||||||
});
|
|
||||||
|
|
||||||
const children = await processPages(node);
|
const children = await processPages(node);
|
||||||
|
const paintStyles = await processPaintStyles();
|
||||||
if (remoteComponentLibrary.remaining() > 0) {
|
const images = await processImages();
|
||||||
children.push({
|
const textStyles = await processTextStyles();
|
||||||
name: 'External Components',
|
|
||||||
children: await translateRemoteChildren()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const styles = await getFillStyles();
|
|
||||||
|
|
||||||
const images = await downloadImages();
|
|
||||||
|
|
||||||
const typographies = await getTextStyles();
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name: node.name,
|
name: node.name,
|
||||||
children,
|
children,
|
||||||
components: componentsLibrary.all(),
|
components: components.all(),
|
||||||
images,
|
images,
|
||||||
styles,
|
paintStyles,
|
||||||
typographies
|
textStyles
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { overridesLibrary } from '@plugin/OverridesLibrary';
|
import { overrides, remoteComponents } from '@plugin/libraries';
|
||||||
import { remoteComponentLibrary } from '@plugin/RemoteComponentLibrary';
|
|
||||||
import {
|
import {
|
||||||
transformAutoLayout,
|
transformAutoLayout,
|
||||||
transformBlend,
|
transformBlend,
|
||||||
|
@ -40,9 +39,7 @@ export const transformInstanceNode = async (
|
||||||
registerTextVariableOverrides(node, primaryComponent);
|
registerTextVariableOverrides(node, primaryComponent);
|
||||||
|
|
||||||
if (node.overrides.length > 0) {
|
if (node.overrides.length > 0) {
|
||||||
node.overrides.forEach(override =>
|
node.overrides.forEach(override => overrides.register(override.id, override.overriddenFields));
|
||||||
overridesLibrary.register(override.id, override.overriddenFields)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -78,11 +75,11 @@ const getPrimaryComponent = (mainComponent: ComponentNode): ComponentNode | Comp
|
||||||
};
|
};
|
||||||
|
|
||||||
const registerExternalComponents = (primaryComponent: ComponentNode | ComponentSetNode): void => {
|
const registerExternalComponents = (primaryComponent: ComponentNode | ComponentSetNode): void => {
|
||||||
if (remoteComponentLibrary.get(primaryComponent.id) !== undefined) {
|
if (remoteComponents.has(primaryComponent.id)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
remoteComponentLibrary.register(primaryComponent.id, primaryComponent);
|
remoteComponents.register(primaryComponent.id, primaryComponent);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getComponentTextPropertyOverrides = (
|
const getComponentTextPropertyOverrides = (
|
||||||
|
@ -131,7 +128,7 @@ const registerTextVariableOverrides = (
|
||||||
});
|
});
|
||||||
|
|
||||||
textNodes.forEach(textNode => {
|
textNodes.forEach(textNode => {
|
||||||
overridesLibrary.register(textNode.id, ['text']);
|
overrides.register(textNode.id, ['text']);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { styleLibrary } from '@plugin/StyleLibrary';
|
import { paintStyles } from '@plugin/libraries';
|
||||||
import { translateImageFill, translateSolidFill } from '@plugin/translators/fills';
|
import { translateImageFill, translateSolidFill } from '@plugin/translators/fills';
|
||||||
import {
|
import {
|
||||||
translateGradientLinearFill,
|
translateGradientLinearFill,
|
||||||
|
@ -47,8 +47,8 @@ export const translateFillStyleId = (
|
||||||
): string | undefined => {
|
): string | undefined => {
|
||||||
if (fillStyleId === figma.mixed || fillStyleId === undefined) return;
|
if (fillStyleId === figma.mixed || fillStyleId === undefined) return;
|
||||||
|
|
||||||
if (!styleLibrary.has(fillStyleId)) {
|
if (!paintStyles.has(fillStyleId)) {
|
||||||
styleLibrary.register(fillStyleId);
|
paintStyles.register(fillStyleId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return fillStyleId;
|
return fillStyleId;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { imagesLibrary } from '@plugin/ImageLibrary';
|
import { images } from '@plugin/libraries';
|
||||||
|
|
||||||
import { Fill } from '@ui/lib/types/utils/fill';
|
import { Fill } from '@ui/lib/types/utils/fill';
|
||||||
import { PartialImageColor } from '@ui/lib/types/utils/imageColor';
|
import { PartialImageColor } from '@ui/lib/types/utils/imageColor';
|
||||||
|
@ -16,8 +16,8 @@ export const translateImageFill = (fill: ImagePaint): Fill | undefined => {
|
||||||
const translateImage = (imageHash: string | null): PartialImageColor | undefined => {
|
const translateImage = (imageHash: string | null): PartialImageColor | undefined => {
|
||||||
if (!imageHash) return;
|
if (!imageHash) return;
|
||||||
|
|
||||||
if (imagesLibrary.get(imageHash) === undefined) {
|
if (!images.has(imageHash)) {
|
||||||
imagesLibrary.register(imageHash, figma.getImageByHash(imageHash));
|
images.register(imageHash, figma.getImageByHash(imageHash));
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {
|
||||||
import { TypographyStyle } from '@ui/lib/types/shapes/textShape';
|
import { TypographyStyle } from '@ui/lib/types/shapes/textShape';
|
||||||
|
|
||||||
export const translateTextStyle = (figmaStyle: TextStyle): TypographyStyle => {
|
export const translateTextStyle = (figmaStyle: TextStyle): TypographyStyle => {
|
||||||
const path = figmaStyle.remote ? 'Remote / ' : '';
|
const name = (figmaStyle.remote ? 'Remote / ' : '') + figmaStyle.name;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name: figmaStyle.name,
|
name: figmaStyle.name,
|
||||||
|
@ -25,8 +25,8 @@ export const translateTextStyle = (figmaStyle: TextStyle): TypographyStyle => {
|
||||||
lineHeight: translateLineHeight(figmaStyle)
|
lineHeight: translateLineHeight(figmaStyle)
|
||||||
},
|
},
|
||||||
typography: {
|
typography: {
|
||||||
path,
|
path: '',
|
||||||
name: figmaStyle.name
|
name
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { textLibrary } from '@plugin/TextLibrary';
|
import { textStyles } from '@plugin/libraries';
|
||||||
import { transformFills } from '@plugin/transformers/partials';
|
import { transformFills } from '@plugin/transformers/partials';
|
||||||
import { translateFontName } from '@plugin/translators/text/font';
|
import { translateFontName } from '@plugin/translators/text/font';
|
||||||
import { TextSegment, translateParagraphProperties } from '@plugin/translators/text/paragraph';
|
import { TextSegment, translateParagraphProperties } from '@plugin/translators/text/paragraph';
|
||||||
|
@ -67,8 +67,8 @@ const hasTextStyle = (segment: TextSegment): boolean => {
|
||||||
const translateTextStyleId = (textStyleId: string | undefined): string | undefined => {
|
const translateTextStyleId = (textStyleId: string | undefined): string | undefined => {
|
||||||
if (textStyleId === undefined) return;
|
if (textStyleId === undefined) return;
|
||||||
|
|
||||||
if (!textLibrary.has(textStyleId)) {
|
if (!textStyles.has(textStyleId)) {
|
||||||
textLibrary.register(textStyleId);
|
textStyles.register(textStyleId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return textStyleId;
|
return textStyleId;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { remoteComponentLibrary } from '@plugin/RemoteComponentLibrary';
|
import { remoteComponents } from '@plugin/libraries';
|
||||||
import { transformGroupNodeLike, transformSceneNode } from '@plugin/transformers';
|
import { transformGroupNodeLike, transformSceneNode } from '@plugin/transformers';
|
||||||
import { transformMaskFigmaIds } from '@plugin/transformers/partials';
|
import { transformMaskFigmaIds } from '@plugin/transformers/partials';
|
||||||
import { sleep } from '@plugin/utils';
|
import { sleep } from '@plugin/utils';
|
||||||
|
@ -71,13 +71,13 @@ export const translateRemoteChildren = async (): Promise<PenpotNode[]> => {
|
||||||
data: 'remote'
|
data: 'remote'
|
||||||
});
|
});
|
||||||
|
|
||||||
while (remoteComponentLibrary.remaining() > 0) {
|
while (remoteComponents.remaining() > 0) {
|
||||||
figma.ui.postMessage({
|
figma.ui.postMessage({
|
||||||
type: 'PROGRESS_TOTAL_ITEMS',
|
type: 'PROGRESS_TOTAL_ITEMS',
|
||||||
data: remoteComponentLibrary.total()
|
data: remoteComponents.total()
|
||||||
});
|
});
|
||||||
|
|
||||||
const child = remoteComponentLibrary.next();
|
const child = remoteComponents.next();
|
||||||
|
|
||||||
const penpotNode = await transformSceneNode(child);
|
const penpotNode = await transformSceneNode(child);
|
||||||
|
|
||||||
|
|
|
@ -3,20 +3,19 @@ import { sleep } from '@plugin/utils/sleep';
|
||||||
import { sendMessage } from '@ui/context';
|
import { sendMessage } from '@ui/context';
|
||||||
import { PenpotFile } from '@ui/lib/types/penpotFile';
|
import { PenpotFile } from '@ui/lib/types/penpotFile';
|
||||||
import { PenpotPage } from '@ui/lib/types/penpotPage';
|
import { PenpotPage } from '@ui/lib/types/penpotPage';
|
||||||
import { idLibrary } from '@ui/parser';
|
|
||||||
import {
|
import {
|
||||||
createColorsLibrary,
|
createColorsLibrary,
|
||||||
createComponentsLibrary,
|
createComponentsLibrary,
|
||||||
createPage,
|
createPage,
|
||||||
createTextLibrary
|
createTextLibrary
|
||||||
} from '@ui/parser/creators';
|
} from '@ui/parser/creators';
|
||||||
import { uiComponents } from '@ui/parser/libraries';
|
import { components, identifiers } from '@ui/parser/libraries';
|
||||||
|
|
||||||
export const buildFile = async (file: PenpotFile, children: PenpotPage[]) => {
|
export const buildFile = async (file: PenpotFile, children: PenpotPage[]) => {
|
||||||
let pagesBuilt = 1;
|
let pagesBuilt = 1;
|
||||||
|
|
||||||
uiComponents.init();
|
components.init();
|
||||||
idLibrary.init();
|
identifiers.init();
|
||||||
|
|
||||||
sendMessage({
|
sendMessage({
|
||||||
type: 'PROGRESS_TOTAL_ITEMS',
|
type: 'PROGRESS_TOTAL_ITEMS',
|
||||||
|
|
|
@ -2,11 +2,11 @@ import { sleep } from '@plugin/utils/sleep';
|
||||||
|
|
||||||
import { sendMessage } from '@ui/context';
|
import { sendMessage } from '@ui/context';
|
||||||
import { PenpotFile } from '@ui/lib/types/penpotFile';
|
import { PenpotFile } from '@ui/lib/types/penpotFile';
|
||||||
import { uiColorLibraries } from '@ui/parser/libraries/UiColorLibraries';
|
import { colors } from '@ui/parser/libraries';
|
||||||
|
|
||||||
export const createColorsLibrary = async (file: PenpotFile) => {
|
export const createColorsLibrary = async (file: PenpotFile) => {
|
||||||
let librariesBuilt = 1;
|
let librariesBuilt = 1;
|
||||||
const libraries = uiColorLibraries.all();
|
const libraries = colors.all();
|
||||||
|
|
||||||
sendMessage({
|
sendMessage({
|
||||||
type: 'PROGRESS_TOTAL_ITEMS',
|
type: 'PROGRESS_TOTAL_ITEMS',
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import { componentsLibrary } from '@plugin/ComponentLibrary';
|
import { components } from '@plugin/libraries/Components';
|
||||||
|
|
||||||
import { PenpotFile } from '@ui/lib/types/penpotFile';
|
import { PenpotFile } from '@ui/lib/types/penpotFile';
|
||||||
import { uiComponents } from '@ui/parser/libraries';
|
import { components as uiComponents } from '@ui/parser/libraries';
|
||||||
import { ComponentRoot } from '@ui/types';
|
import { ComponentRoot } from '@ui/types';
|
||||||
|
|
||||||
import { createArtboard } from '.';
|
import { createArtboard } from '.';
|
||||||
|
|
||||||
export const createComponent = (file: PenpotFile, { figmaId }: ComponentRoot) => {
|
export const createComponent = (file: PenpotFile, { figmaId }: ComponentRoot) => {
|
||||||
const component = componentsLibrary.get(figmaId);
|
const component = components.get(figmaId);
|
||||||
|
|
||||||
if (!component) {
|
if (!component) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { PenpotFile } from '@ui/lib/types/penpotFile';
|
import { PenpotFile } from '@ui/lib/types/penpotFile';
|
||||||
import { parseFigmaId } from '@ui/parser';
|
import { parseFigmaId } from '@ui/parser';
|
||||||
import { uiComponents } from '@ui/parser/libraries';
|
import { components } from '@ui/parser/libraries';
|
||||||
import { ComponentInstance } from '@ui/types';
|
import { ComponentInstance } from '@ui/types';
|
||||||
|
|
||||||
import { createArtboard } from '.';
|
import { createArtboard } from '.';
|
||||||
|
@ -17,7 +17,7 @@ export const createComponentInstance = (
|
||||||
}: ComponentInstance
|
}: ComponentInstance
|
||||||
) => {
|
) => {
|
||||||
const uiComponent =
|
const uiComponent =
|
||||||
uiComponents.get(mainComponentFigmaId) ?? createUiComponent(file, mainComponentFigmaId);
|
components.get(mainComponentFigmaId) ?? createUiComponent(file, mainComponentFigmaId);
|
||||||
|
|
||||||
if (!uiComponent) {
|
if (!uiComponent) {
|
||||||
return;
|
return;
|
||||||
|
@ -43,7 +43,7 @@ const createUiComponent = (file: PenpotFile, mainComponentFigmaId: string) => {
|
||||||
mainInstanceId
|
mainInstanceId
|
||||||
};
|
};
|
||||||
|
|
||||||
uiComponents.register(mainComponentFigmaId, uiComponent);
|
components.register(mainComponentFigmaId, uiComponent);
|
||||||
|
|
||||||
return uiComponent;
|
return uiComponent;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { componentsLibrary } from '@plugin/ComponentLibrary';
|
import { components } from '@plugin/libraries/Components';
|
||||||
import { sleep } from '@plugin/utils/sleep';
|
import { sleep } from '@plugin/utils/sleep';
|
||||||
|
|
||||||
import { sendMessage } from '@ui/context';
|
import { sendMessage } from '@ui/context';
|
||||||
import { PenpotFile } from '@ui/lib/types/penpotFile';
|
import { PenpotFile } from '@ui/lib/types/penpotFile';
|
||||||
import { symbolFills, symbolStrokes } from '@ui/parser/creators/symbols';
|
import { symbolFills, symbolStrokes } from '@ui/parser/creators/symbols';
|
||||||
import { UiComponent, uiComponents } from '@ui/parser/libraries';
|
import { UiComponent, components as uiComponents } from '@ui/parser/libraries';
|
||||||
|
|
||||||
import { createItems } from '.';
|
import { createItems } from '.';
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ export const createComponentsLibrary = async (file: PenpotFile) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const createComponentLibrary = async (file: PenpotFile, uiComponent: UiComponent) => {
|
const createComponentLibrary = async (file: PenpotFile, uiComponent: UiComponent) => {
|
||||||
const component = componentsLibrary.get(uiComponent.componentFigmaId);
|
const component = components.get(uiComponent.componentFigmaId);
|
||||||
|
|
||||||
if (!component) {
|
if (!component) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { PenpotFile } from '@ui/lib/types/penpotFile';
|
||||||
import { Paragraph, TextContent, TextNode, TextShape } from '@ui/lib/types/shapes/textShape';
|
import { Paragraph, TextContent, TextNode, TextShape } from '@ui/lib/types/shapes/textShape';
|
||||||
import { parseFigmaId } from '@ui/parser';
|
import { parseFigmaId } from '@ui/parser';
|
||||||
import { symbolFills, symbolStrokes } from '@ui/parser/creators/symbols';
|
import { symbolFills, symbolStrokes } from '@ui/parser/creators/symbols';
|
||||||
import { uiTextLibraries } from '@ui/parser/libraries/UiTextLibraries';
|
import { typographies } from '@ui/parser/libraries';
|
||||||
|
|
||||||
export const createText = (
|
export const createText = (
|
||||||
file: PenpotFile,
|
file: PenpotFile,
|
||||||
|
@ -36,7 +36,7 @@ const parseTextStyle = (text: Paragraph | TextNode, textStyleId?: string): Parag
|
||||||
let textStyle = text;
|
let textStyle = text;
|
||||||
textStyle.fills = symbolFills(text.fillStyleId, text.fills);
|
textStyle.fills = symbolFills(text.fillStyleId, text.fills);
|
||||||
|
|
||||||
const libraryStyle = textStyleId ? uiTextLibraries.get(textStyleId) : undefined;
|
const libraryStyle = textStyleId ? typographies.get(textStyleId) : undefined;
|
||||||
|
|
||||||
if (libraryStyle) {
|
if (libraryStyle) {
|
||||||
textStyle = {
|
textStyle = {
|
||||||
|
|
|
@ -2,11 +2,11 @@ import { sleep } from '@plugin/utils/sleep';
|
||||||
|
|
||||||
import { sendMessage } from '@ui/context';
|
import { sendMessage } from '@ui/context';
|
||||||
import { PenpotFile } from '@ui/lib/types/penpotFile';
|
import { PenpotFile } from '@ui/lib/types/penpotFile';
|
||||||
import { uiTextLibraries } from '@ui/parser/libraries/UiTextLibraries';
|
import { typographies } from '@ui/parser/libraries';
|
||||||
|
|
||||||
export const createTextLibrary = async (file: PenpotFile) => {
|
export const createTextLibrary = async (file: PenpotFile) => {
|
||||||
let librariesBuilt = 1;
|
let librariesBuilt = 1;
|
||||||
const libraries = uiTextLibraries.all();
|
const libraries = typographies.all();
|
||||||
|
|
||||||
sendMessage({
|
sendMessage({
|
||||||
type: 'PROGRESS_TOTAL_ITEMS',
|
type: 'PROGRESS_TOTAL_ITEMS',
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
import { Fill } from '@ui/lib/types/utils/fill';
|
import { Fill } from '@ui/lib/types/utils/fill';
|
||||||
import { ImageColor, PartialImageColor } from '@ui/lib/types/utils/imageColor';
|
import { ImageColor, PartialImageColor } from '@ui/lib/types/utils/imageColor';
|
||||||
import { uiImages } from '@ui/parser/libraries';
|
import { colors, images } from '@ui/parser/libraries';
|
||||||
import { uiColorLibraries } from '@ui/parser/libraries/UiColorLibraries';
|
|
||||||
|
|
||||||
export const symbolFills = (fillStyleId?: string, fills?: Fill[]): Fill[] | undefined => {
|
export const symbolFills = (fillStyleId?: string, fills?: Fill[]): Fill[] | undefined => {
|
||||||
const nodeFills = fillStyleId ? uiColorLibraries.get(fillStyleId)?.fills : fills;
|
const nodeFills = fillStyleId ? colors.get(fillStyleId)?.fills : fills;
|
||||||
|
|
||||||
if (!nodeFills) return;
|
if (!nodeFills) return;
|
||||||
|
|
||||||
|
@ -22,7 +21,7 @@ export const symbolFillImage = (
|
||||||
): ImageColor | undefined => {
|
): ImageColor | undefined => {
|
||||||
if (!isPartialFillColor(fillImage)) return fillImage;
|
if (!isPartialFillColor(fillImage)) return fillImage;
|
||||||
|
|
||||||
return uiImages.get(fillImage.imageHash);
|
return images.get(fillImage.imageHash);
|
||||||
};
|
};
|
||||||
|
|
||||||
const isPartialFillColor = (
|
const isPartialFillColor = (
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
export * from './IdLibrary';
|
|
||||||
export * from './parse';
|
export * from './parse';
|
||||||
export * from './parseImage';
|
export * from './parseImage';
|
||||||
export * from './parseFigmaId';
|
export * from './parseFigmaId';
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { FillStyle } from '@ui/lib/types/utils/fill';
|
import { FillStyle } from '@ui/lib/types/utils/fill';
|
||||||
|
|
||||||
class UiColorLibraries {
|
class Colors {
|
||||||
private libraries: Map<string, FillStyle> = new Map();
|
private libraries: Map<string, FillStyle> = new Map();
|
||||||
|
|
||||||
public register(id: string, fillStyle: FillStyle) {
|
public register(id: string, fillStyle: FillStyle) {
|
||||||
|
@ -16,4 +16,4 @@ class UiColorLibraries {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const uiColorLibraries = new UiColorLibraries();
|
export const colors = new Colors();
|
|
@ -7,24 +7,24 @@ export type UiComponent = {
|
||||||
componentFigmaId: string;
|
componentFigmaId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
class UiComponents {
|
class Components {
|
||||||
private components: Record<string, UiComponent> = {};
|
private components: Map<string, UiComponent> = new Map();
|
||||||
|
|
||||||
public register(id: string, component: UiComponent) {
|
public register(id: string, component: UiComponent) {
|
||||||
this.components[id] = component;
|
this.components.set(id, component);
|
||||||
}
|
}
|
||||||
|
|
||||||
public get(id: string): UiComponent | undefined {
|
public get(id: string): UiComponent | undefined {
|
||||||
return this.components[id];
|
return this.components.get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public all(): UiComponent[] {
|
public all(): UiComponent[] {
|
||||||
return Object.values(this.components);
|
return Array.from(this.components.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
public init() {
|
public init() {
|
||||||
this.components = {};
|
this.components.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const uiComponents = new UiComponents();
|
export const components = new Components();
|
|
@ -1,6 +1,6 @@
|
||||||
import { Uuid } from '@ui/lib/types/utils/uuid';
|
import { Uuid } from '@ui/lib/types/utils/uuid';
|
||||||
|
|
||||||
class IdLibrary {
|
class Identifiers {
|
||||||
private idMap: Map<string, Uuid> = new Map();
|
private idMap: Map<string, Uuid> = new Map();
|
||||||
|
|
||||||
public init() {
|
public init() {
|
||||||
|
@ -16,4 +16,4 @@ class IdLibrary {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const idLibrary = new IdLibrary();
|
export const identifiers = new Identifiers();
|
23
ui-src/parser/libraries/Images.ts
Normal file
23
ui-src/parser/libraries/Images.ts
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
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,6 +1,6 @@
|
||||||
import { TypographyStyle } from '@ui/lib/types/shapes/textShape';
|
import { TypographyStyle } from '@ui/lib/types/shapes/textShape';
|
||||||
|
|
||||||
class UiTextLibraries {
|
class Typographies {
|
||||||
private libraries: Map<string, TypographyStyle> = new Map();
|
private libraries: Map<string, TypographyStyle> = new Map();
|
||||||
|
|
||||||
public register(id: string, textStyle: TypographyStyle) {
|
public register(id: string, textStyle: TypographyStyle) {
|
||||||
|
@ -16,4 +16,4 @@ class UiTextLibraries {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const uiTextLibraries = new UiTextLibraries();
|
export const typographies = new Typographies();
|
|
@ -1,23 +0,0 @@
|
||||||
import { ImageColor } from '@ui/lib/types/utils/imageColor';
|
|
||||||
|
|
||||||
class UiImages {
|
|
||||||
private images: Record<string, ImageColor> = {};
|
|
||||||
|
|
||||||
public register(id: string, image: ImageColor) {
|
|
||||||
this.images[id] = image;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get(id: string): ImageColor | undefined {
|
|
||||||
return this.images[id];
|
|
||||||
}
|
|
||||||
|
|
||||||
public all(): ImageColor[] {
|
|
||||||
return Object.values(this.images);
|
|
||||||
}
|
|
||||||
|
|
||||||
public init() {
|
|
||||||
this.images = {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const uiImages = new UiImages();
|
|
|
@ -1,3 +1,5 @@
|
||||||
export * from './UiComponents';
|
export * from './Identifiers';
|
||||||
export * from './UiImages';
|
export * from './Colors';
|
||||||
export * from './UiColorLibraries';
|
export * from './Components';
|
||||||
|
export * from './Images';
|
||||||
|
export * from './Typographies';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { componentsLibrary } from '@plugin/ComponentLibrary';
|
import { components as componentsLibrary } from '@plugin/libraries/Components';
|
||||||
// @TODO: Direct import on purpose, to avoid problems with the tsc linting
|
// @TODO: Direct import on purpose, to avoid problems with the tsc linting
|
||||||
import { sleep } from '@plugin/utils/sleep';
|
import { sleep } from '@plugin/utils/sleep';
|
||||||
|
|
||||||
|
@ -8,8 +8,7 @@ import { PenpotFile } from '@ui/lib/types/penpotFile';
|
||||||
import { TypographyStyle } from '@ui/lib/types/shapes/textShape';
|
import { TypographyStyle } from '@ui/lib/types/shapes/textShape';
|
||||||
import { FillStyle } from '@ui/lib/types/utils/fill';
|
import { FillStyle } from '@ui/lib/types/utils/fill';
|
||||||
import { buildFile } from '@ui/parser/creators';
|
import { buildFile } from '@ui/parser/creators';
|
||||||
import { uiColorLibraries, uiImages } from '@ui/parser/libraries';
|
import { colors, typographies, images as uiImages } from '@ui/parser/libraries';
|
||||||
import { uiTextLibraries } from '@ui/parser/libraries/UiTextLibraries';
|
|
||||||
import { PenpotDocument } from '@ui/types';
|
import { PenpotDocument } from '@ui/types';
|
||||||
|
|
||||||
import { parseImage } from '.';
|
import { parseImage } from '.';
|
||||||
|
@ -71,7 +70,7 @@ const prepareTypographyLibraries = async (
|
||||||
style.textStyle.typographyRefFile = file.getId();
|
style.textStyle.typographyRefFile = file.getId();
|
||||||
style.typography.id = typographyId;
|
style.typography.id = typographyId;
|
||||||
|
|
||||||
uiTextLibraries.register(key, style);
|
typographies.register(key, style);
|
||||||
|
|
||||||
sendMessage({
|
sendMessage({
|
||||||
type: 'PROGRESS_PROCESSED_ITEMS',
|
type: 'PROGRESS_PROCESSED_ITEMS',
|
||||||
|
@ -108,7 +107,7 @@ const prepareColorLibraries = async (file: PenpotFile, styles: Record<string, Fi
|
||||||
fillStyle.colors[index].refFile = file.getId();
|
fillStyle.colors[index].refFile = file.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
uiColorLibraries.register(key, fillStyle);
|
colors.register(key, fillStyle);
|
||||||
|
|
||||||
sendMessage({
|
sendMessage({
|
||||||
type: 'PROGRESS_PROCESSED_ITEMS',
|
type: 'PROGRESS_PROCESSED_ITEMS',
|
||||||
|
@ -124,16 +123,16 @@ export const parse = async ({
|
||||||
children = [],
|
children = [],
|
||||||
components,
|
components,
|
||||||
images,
|
images,
|
||||||
styles,
|
paintStyles,
|
||||||
typographies
|
textStyles
|
||||||
}: PenpotDocument) => {
|
}: PenpotDocument) => {
|
||||||
componentsLibrary.init(components);
|
componentsLibrary.init(components);
|
||||||
|
|
||||||
const file = createFile(name);
|
const file = createFile(name);
|
||||||
|
|
||||||
await optimizeImages(images);
|
await optimizeImages(images);
|
||||||
await prepareColorLibraries(file, styles);
|
await prepareColorLibraries(file, paintStyles);
|
||||||
await prepareTypographyLibraries(file, typographies);
|
await prepareTypographyLibraries(file, textStyles);
|
||||||
|
|
||||||
return buildFile(file, children);
|
return buildFile(file, children);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { PenpotFile } from '@ui/lib/types/penpotFile';
|
import { PenpotFile } from '@ui/lib/types/penpotFile';
|
||||||
import { Uuid } from '@ui/lib/types/utils/uuid';
|
import { Uuid } from '@ui/lib/types/utils/uuid';
|
||||||
|
import { identifiers } from '@ui/parser/libraries';
|
||||||
import { idLibrary } from '.';
|
|
||||||
|
|
||||||
export const parseFigmaId = (
|
export const parseFigmaId = (
|
||||||
file: PenpotFile,
|
file: PenpotFile,
|
||||||
|
@ -16,12 +15,12 @@ export const parseFigmaId = (
|
||||||
return file.newId();
|
return file.newId();
|
||||||
}
|
}
|
||||||
|
|
||||||
const id = idLibrary.get(figmaId);
|
const id = identifiers.get(figmaId);
|
||||||
if (id) {
|
if (id) {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
const newId = file.newId();
|
const newId = file.newId();
|
||||||
idLibrary.register(figmaId, newId);
|
identifiers.register(figmaId, newId);
|
||||||
return newId;
|
return newId;
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,6 +8,6 @@ export type PenpotDocument = {
|
||||||
children?: PenpotPage[];
|
children?: PenpotPage[];
|
||||||
components: Record<string, ComponentShape>;
|
components: Record<string, ComponentShape>;
|
||||||
images: Record<string, Uint8Array>;
|
images: Record<string, Uint8Array>;
|
||||||
styles: Record<string, FillStyle>;
|
paintStyles: Record<string, FillStyle>;
|
||||||
typographies: Record<string, TypographyStyle>;
|
textStyles: Record<string, TypographyStyle>;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue