0
Fork 0
mirror of https://github.com/penpot/penpot-exporter-figma-plugin.git synced 2025-01-08 16:10:07 -05:00

Components Library ()

* components library management

* components library management

* fixes

* fixes
This commit is contained in:
Alex Sánchez 2024-05-29 17:33:29 +02:00 committed by GitHub
parent 32aafbcf9d
commit 5d4ace337b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 138 additions and 70 deletions

View file

@ -0,0 +1,23 @@
import { ComponentShape } from '@ui/lib/types/shapes/componentShape';
class ComponentLibrary {
private components: Record<string, ComponentShape> = {};
public register(id: string, component: ComponentShape) {
this.components[id] = component;
}
public get(id: string): ComponentShape | undefined {
return this.components[id];
}
public all(): Record<string, ComponentShape> {
return this.components;
}
public init(components: Record<string, ComponentShape>): void {
this.components = components;
}
}
export const componentsLibrary = new ComponentLibrary();

View file

@ -1,5 +1,7 @@
import { componentsLibrary } from '@plugin/ComponentLibrary';
import {
transformBlend,
transformChildren,
transformCornerRadius,
transformDimensionAndPosition,
transformEffects,
@ -8,16 +10,15 @@ import {
transformSceneNode,
transformStrokes
} from '@plugin/transformers/partials';
import { transformChildren } from '@plugin/transformers/partials';
import { ComponentShape } from '@ui/lib/types/shapes/componentShape';
import { ComponentRoot } from '@ui/types';
export const transformComponentNode = async (
node: ComponentNode,
baseX: number,
baseY: number
): Promise<ComponentShape> => {
return {
): Promise<ComponentRoot> => {
componentsLibrary.register(node.id, {
type: 'component',
name: node.name,
path: '',
@ -30,5 +31,10 @@ export const transformComponentNode = async (
...transformCornerRadius(node),
...(await transformChildren(node, baseX + node.x, baseY + node.y)),
...transformDimensionAndPosition(node, baseX, baseY)
});
return {
figmaId: node.id,
type: 'component'
};
};

View file

@ -1,10 +1,13 @@
import { PenpotDocument } from '@ui/lib/types/penpotDocument';
import { componentsLibrary } from '@plugin/ComponentLibrary';
import { PenpotDocument } from '@ui/types';
import { transformPageNode } from '.';
export const transformDocumentNode = async (node: DocumentNode): Promise<PenpotDocument> => {
return {
name: node.name,
children: await Promise.all(node.children.map(child => transformPageNode(child)))
children: await Promise.all(node.children.map(child => transformPageNode(child))),
components: componentsLibrary.all()
};
};

View file

@ -1,4 +1,4 @@
import { PenpotNode } from '@ui/lib/types/penpotNode';
import { PenpotNode } from '@ui/types';
import {
transformBooleanNode,

View file

@ -1,6 +1,6 @@
import { transformGroupNodeLike, transformSceneNode } from '@plugin/transformers';
import { PenpotNode } from '@ui/lib/types/penpotNode';
import { PenpotNode } from '@ui/types';
/**
* Translates the children of a node that acts as a mask.

View file

@ -3,8 +3,8 @@ import { useEffect, useState } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { Stack } from '@ui/components/Stack';
import { PenpotDocument } from '@ui/lib/types/penpotDocument';
import { parse } from '@ui/parser';
import { PenpotDocument } from '@ui/types';
import { MissingFontsSection } from './MissingFontsSection';

View file

@ -1,6 +0,0 @@
import { PenpotPage } from './penpotPage';
export type PenpotDocument = {
name: string;
children?: PenpotPage[];
};

View file

@ -1,3 +1,3 @@
import { PenpotNode } from '@ui/lib/types/penpotNode';
import { PenpotNode } from '@ui/types';
export type Children = { children?: PenpotNode[] };

View file

@ -1,38 +1,34 @@
import { componentsLibrary } from '@plugin/ComponentLibrary';
import { PenpotFile } from '@ui/lib/types/penpotFile';
import { ComponentShape } from '@ui/lib/types/shapes/componentShape';
import { components } from '@ui/parser/libraries';
import { uiComponents } from '@ui/parser/libraries';
import { ComponentRoot } from '@ui/types';
import { createArtboard } from '.';
export const createComponent = (
file: PenpotFile,
{ type, path, children = [], ...rest }: ComponentShape
) => {
export const createComponent = (file: PenpotFile, { figmaId }: ComponentRoot) => {
const frameId = file.newId();
const componentId = file.newId();
const commonStructure = {
...rest,
children,
const component = componentsLibrary.get(figmaId);
if (!component) {
return;
}
createArtboard(file, {
...component,
componentFile: file.getId(),
componentId: componentId,
componentRoot: true,
mainInstance: true
};
createArtboard(file, {
...commonStructure,
id: frameId,
mainInstance: true,
id: frameId,
type: 'frame'
});
components.add({
...commonStructure,
id: componentId,
mainInstanceId: frameId,
uiComponents.register(figmaId, {
componentId,
mainInstancePage: file.getCurrentPageId(),
path,
type
componentFigmaId: figmaId,
mainInstanceId: frameId
});
};

View file

@ -1,12 +1,29 @@
import { componentsLibrary } from '@plugin/ComponentLibrary';
import { PenpotFile } from '@ui/lib/types/penpotFile';
import { ComponentShape } from '@ui/lib/types/shapes/componentShape';
import { components } from '@ui/parser/libraries';
import { uiComponents } from '@ui/parser/libraries';
import { createItems } from '.';
export const createComponentLibrary = (file: PenpotFile) => {
components.get().forEach(({ children = [], ...rest }: ComponentShape) => {
file.startComponent(rest);
uiComponents.all().forEach(uiComponent => {
const component = componentsLibrary.get(uiComponent.componentFigmaId);
if (!component) {
return;
}
const { children = [], ...rest } = component;
file.startComponent({
...rest,
id: uiComponent.componentId,
componentId: uiComponent.componentId,
mainInstancePage: uiComponent.mainInstancePage,
mainInstanceId: uiComponent.mainInstanceId,
componentRoot: true,
mainInstance: true,
componentFile: file.getId()
});
createItems(file, children);

View file

@ -1,5 +1,5 @@
import { PenpotFile } from '@ui/lib/types/penpotFile';
import { PenpotNode } from '@ui/lib/types/penpotNode';
import { PenpotNode } from '@ui/types';
import {
createArtboard,

View file

@ -1,19 +0,0 @@
import { ComponentShape } from '@ui/lib/types/shapes/componentShape';
class Components {
private components: ComponentShape[] = [];
public add(component: ComponentShape) {
this.components.push(component);
}
public get() {
return this.components;
}
public clear() {
this.components = [];
}
}
export const components = new Components();

View file

@ -0,0 +1,30 @@
import { Uuid } from '@ui/lib/types/utils/uuid';
type UiComponent = {
componentId: Uuid;
mainInstancePage: Uuid;
mainInstanceId: Uuid;
componentFigmaId: string;
};
class UiComponents {
private components: Record<string, UiComponent> = {};
public register(id: string, component: UiComponent) {
this.components[id] = component;
}
public get(id: string): UiComponent | undefined {
return this.components[id];
}
public all(): UiComponent[] {
return Object.values(this.components);
}
public init() {
this.components = {};
}
}
export const uiComponents = new UiComponents();

View file

@ -1 +1 @@
export * from './Components';
export * from './UiComponents';

View file

@ -1,10 +1,13 @@
import { createFile } from '@ui/lib/penpot';
import { PenpotDocument } from '@ui/lib/types/penpotDocument';
import { createComponentLibrary, createPage } from '@ui/parser/creators';
import { components } from '@ui/parser/libraries';
import { componentsLibrary } from '@plugin/ComponentLibrary';
export const parse = ({ name, children = [] }: PenpotDocument) => {
components.clear();
import { createFile } from '@ui/lib/penpot';
import { createComponentLibrary, createPage } from '@ui/parser/creators';
import { uiComponents } from '@ui/parser/libraries/UiComponents';
import { PenpotDocument } from '@ui/types';
export const parse = ({ name, children = [], components }: PenpotDocument) => {
componentsLibrary.init(components);
uiComponents.init();
const file = createFile(name);

View file

@ -0,0 +1,4 @@
export type ComponentRoot = {
figmaId: string;
type: 'component';
};

3
ui-src/types/index.ts Normal file
View file

@ -0,0 +1,3 @@
export * from './componentRoot';
export * from './penpotDocument';
export * from './penpotNode';

View file

@ -0,0 +1,8 @@
import { PenpotPage } from '@ui/lib/types/penpotPage';
import { ComponentShape } from '@ui/lib/types/shapes/componentShape';
export type PenpotDocument = {
name: string;
children?: PenpotPage[];
components: Record<string, ComponentShape>;
};

View file

@ -1,11 +1,11 @@
import { BoolShape } from '@ui/lib/types/shapes/boolShape';
import { CircleShape } from '@ui/lib/types/shapes/circleShape';
import { ComponentShape } from '@ui/lib/types/shapes/componentShape';
import { FrameShape } from '@ui/lib/types/shapes/frameShape';
import { GroupShape } from '@ui/lib/types/shapes/groupShape';
import { PathShape } from '@ui/lib/types/shapes/pathShape';
import { RectShape } from '@ui/lib/types/shapes/rectShape';
import { TextShape } from '@ui/lib/types/shapes/textShape';
import { ComponentRoot } from '@ui/types';
export type PenpotNode =
| FrameShape
@ -15,4 +15,4 @@ export type PenpotNode =
| CircleShape
| TextShape
| BoolShape
| ComponentShape;
| ComponentRoot;