0
Fork 0
mirror of https://github.com/penpot/penpot-plugins.git synced 2025-01-21 06:02:34 -05:00

feat: modify shapes from a plugin poc

This commit is contained in:
alonso.torres 2024-04-18 17:11:48 +02:00 committed by Alonso Torres
parent f92b923585
commit 146a7e1066
5 changed files with 78 additions and 43 deletions

View file

@ -67,3 +67,13 @@ h1 {
font-size: 11px;
padding-inline-start: var(--spacing-12);
}
.name-wrap {
display: flex;
gap: 1rem;
margin-bottom: 1rem;
}
.name-wrap input {
flex: 1;
}

View file

@ -9,9 +9,10 @@ export class AppElement extends HTMLElement {
#fileId = null;
#revn = 0;
refreshPage(pageId: string, name: string) {
console.log('refreshPage', pageId, name);
#nameSubmit = null;
#nameInput = null;
refreshPage(pageId: string, name: string) {
const projectName = document.getElementById('project-name');
this.#pageId = pageId;
@ -20,57 +21,68 @@ export class AppElement extends HTMLElement {
}
}
refreshSelectionId(selection: string[]) {
refreshSelection(selection: PenpotShape[]) {
this.#selection = selection;
const selectionId = document.getElementById('selection-id');
if (selectionId) {
selectionId.innerText = [...this.#selection].join(",");
if (selection && selection.length > 0) {
this.#nameInput.value = this.#selection[0].name;
} else {
this.#nameInput.value = "";
}
}
connectedCallback() {
window.addEventListener('message', (event) => {
if (event.data.type === 'file') {
this.#fileId = event.data.content.id;
this.#revn = event.data.content.revn;
} else if (event.data.type === 'page') {
console.log(">>UI", event.data.content.shapes);
this.refreshPage(event.data.content.page.id, event.data.content.page.name);
} else if (event.data.type === 'selection') {
this.refreshSelectionId(event.data.content);
} else if (event.data.type === 'init') {
console.log("Content", event.data.content);
this.#fileId = event.data.content.fileId;
this.#revn = event.data.content.revn;
this.refreshPage(event.data.content.pageId, event.data.content.name);
this.refreshSelectionId(event.data.content.selection);
this.setAttribute('data-theme', event.data.content.theme);
} else if (event.data.type === 'theme') {
this.setAttribute('data-theme', event.data.content);
}
});
this.innerHTML = `
<div class="wrapper">
<h1>Test area!</h1>
<p>Current project name: <span id="project-name">Unknown</span></p>
<p>Selection id: <span id="selection-id">Unknown</span></p>
<div class="name-wrap">
<label>Selected Shape: </label>
<input id="name-input" type="text"></input>
<button id="name-submit" type="button">Update</button>
</div>
<p>
<button type="button" data-appearance="primary" data-variant="destructive" class="act-close-plugin">Close plugin</button>
</p>
</div>
`;
this.#nameSubmit = document.getElementById<HTMLElement>('name-submit');
this.#nameInput = document.getElementById<HTMLElement>('name-input');
window.addEventListener('message', (event) => {
if (event.data.type === 'file') {
this.#fileId = event.data.content.id;
this.#revn = event.data.content.revn;
} else if (event.data.type === 'page') {
this.refreshPage(event.data.content.page.id, event.data.content.page.name);
} else if (event.data.type === 'selection') {
this.refreshSelection(event.data.content.selection);
} else if (event.data.type === 'init') {
this.#fileId = event.data.content.fileId;
this.#revn = event.data.content.revn;
this.refreshPage(event.data.content.pageId, event.data.content.name);
this.refreshSelection(event.data.content.selection);
this.setAttribute('data-theme', event.data.content.theme);
} else if (event.data.type === 'theme') {
this.setAttribute('data-theme', event.data.content);
}
});
const closeAction = this.querySelector<HTMLElement>('.act-close-plugin');
closeAction?.addEventListener('click', () => {
parent.postMessage({ content: 'close' }, '*');
});
parent.postMessage({ content: 'ready' }, '*');
console.log(this.#nameSubmit);
this.#nameSubmit?.addEventListener('click', (e) => {
const id = this.#selection[0].id;
const name = this.#nameInput.value;
parent.postMessage({ content: 'change-name', data: { id, name } }, '*');
});
}
}
customElements.define('app-root', AppElement);

View file

@ -3,7 +3,7 @@ penpot.ui.open('Plugin name', 'http://localhost:4202', {
height: 600,
});
penpot.ui.onMessage<{ content: string }>((message) => {
penpot.ui.onMessage<{ content: string; data: unknown }>((message) => {
if (message.content === 'close') {
penpot.closePlugin();
} else if (message.content === 'ready') {
@ -22,9 +22,14 @@ penpot.ui.onMessage<{ content: string }>((message) => {
fileId: file.id,
revn: file.revn,
theme: penpot.getTheme(),
selection: penpot.getSelected(),
selection: penpot.getSelectedShapes(),
},
});
} else if (message.content === 'change-name') {
const shape = penpot.getPage()?.getShapeById('' + (message.data as {id: string}).id);
if (shape) {
shape.name = (message.data as {name: string}).name;
}
}
});
@ -49,8 +54,8 @@ penpot.on('filechange', () => {
});
penpot.on('selectionchange', () => {
const selected: string[] = penpot.getSelected();
penpot.ui.sendMessage({ type: 'selection', content: selected });
const selection = penpot.getSelectedShapes();
penpot.ui.sendMessage({ type: 'selection', content: { selection } });
});
penpot.on('themechange', (theme) => {

View file

@ -7,6 +7,7 @@ export interface PenpotFile {
export interface PenpotPage {
id: string;
name: string;
getShapeById(id: string): PenpotShape | null;
findShapes(): PenpotShape[];
}

View file

@ -5,21 +5,28 @@ import { initInstaller } from './lib/installer';
import { ɵloadPlugin, setContext } from './lib/load-plugin';
import * as api from './lib/api';
console.log('Loading plugin system');
repairIntrinsics({
evalTaming: 'unsafeEval',
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function initialize(context: any) {
globalThis.ɵloadPlugin = ɵloadPlugin;
initInstaller();
globalThis.initPluginsRuntime = (context: PenpotContext) => {
if (context) {
console.log('Initialize context');
/* eslint-disable */
setContext(context);
globalThis.ɵcontext = context;
globalThis.ɵloadPlugin = ɵloadPlugin;
initInstaller();
for (const event of api.validEvents) {
context.addListener(event, api.triggerEvent.bind(null, event));
/* eslint-disable */
setContext(context);
for (const event of api.validEvents) {
context.addListener(event, api.triggerEvent.bind(null, event));
}
/* eslint-enable */
}
/* eslint-enable */
}