diff --git a/apps/example-plugin/src/app/app.element.ts b/apps/example-plugin/src/app/app.element.ts
index ccecf30..91aa604 100644
--- a/apps/example-plugin/src/app/app.element.ts
+++ b/apps/example-plugin/src/app/app.element.ts
@@ -4,23 +4,33 @@ import './app.element.css';
export class AppElement extends HTMLElement {
public static observedAttributes = [];
+ refreshPageName(name: string) {
+ const projectName = document.getElementById('project-name');
+
+ if (projectName) {
+ projectName.innerText = name;
+ }
+ }
+
+ refreshSelectionId(selection: string) {
+ const selectionId = document.getElementById('selection-id');
+
+ if (selectionId) {
+ selectionId.innerText = selection;
+ }
+ }
+
connectedCallback() {
- window.addEventListener('message', function (event) {
+ window.addEventListener('message', (event) => {
if (event.data.type === 'pingpong') {
console.log('iframe', event.data.content);
} else if (event.data.type === 'page') {
- console.log('iframe', event.data);
- const projectName = document.getElementById('project-name');
-
- if (projectName) {
- projectName.innerText = event.data.content;
- }
+ this.refreshPageName(event.data.content);
+ } else if (event.data.type === 'selection') {
+ this.refreshSelectionId(event.data.content);
} else if (event.data.type === 'init') {
- const projectName = document.getElementById('project-name');
-
- if (projectName) {
- projectName.innerText = event.data.content.name;
- }
+ this.refreshPageName(event.data.content.name);
+ this.refreshSelectionId(event.data.content.selection);
}
});
@@ -29,6 +39,7 @@ export class AppElement extends HTMLElement {
Test area
Current project name: Unknown
+ Selection id: Unknown
diff --git a/apps/example-plugin/src/plugin.ts b/apps/example-plugin/src/plugin.ts
index 2ce2a3a..b1d8b4b 100644
--- a/apps/example-plugin/src/plugin.ts
+++ b/apps/example-plugin/src/plugin.ts
@@ -26,6 +26,7 @@ penpot.ui.onMessage((message) => {
type: 'init',
content: {
name: penpot.getPageState().name,
+ selection: penpot.getSelection(),
},
});
}
@@ -34,3 +35,7 @@ penpot.ui.onMessage((message) => {
penpot.on('pagechange', (page) => {
penpot.ui.sendMessage({ type: 'page', content: page.name });
});
+
+penpot.on('selectionchange', (id) => {
+ penpot.ui.sendMessage({ type: 'selection', content: id });
+});
diff --git a/docs/index.mustache b/docs/index.mustache
deleted file mode 100644
index 0f074f0..0000000
--- a/docs/index.mustache
+++ /dev/null
@@ -1,72 +0,0 @@
-
-
-
-
-
- Penpot - Design Freedom for Teams
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{#isDebug}}
-
- {{/isDebug}}
-
-
-
-
-
-
-
-
- {{# manifest}}
-
-
-
- {{/manifest}}
-
-
-
- {{>../public/images/sprites/symbol/icons.svg}}
- {{>../public/images/sprites/symbol/cursors.svg}}
-
-
- {{# manifest}}
-
-
-
-
-
- {{/manifest}}
-
-
-
-
-
-
-
-
diff --git a/docs/plugin-usage.md b/docs/plugin-usage.md
index 9f49cc6..bc4d892 100644
--- a/docs/plugin-usage.md
+++ b/docs/plugin-usage.md
@@ -7,6 +7,19 @@ penpot.ui.open('Plugin name', 'http://localhost:4201', {
});
```
+Get state:
+
+```ts
+// file file state
+penpot.ui.getFileState();
+
+// file page state
+penpot.ui.getFileState();
+
+// selection id
+penpot.ui.getSelection();
+```
+
### Messages
Receive message from iframe:
@@ -39,7 +52,7 @@ window.addEventListener('message', function (event) {
### Events
-Current events `pagechange` and `filechange`.
+Current events `pagechange`, `filechange` and `selectionchange`.
```ts
const event = (page) => {
diff --git a/libs/plugins-runtime/README.md b/libs/plugins-runtime/README.md
index 54dc2e8..388016e 100644
--- a/libs/plugins-runtime/README.md
+++ b/libs/plugins-runtime/README.md
@@ -2,8 +2,6 @@
Go to to the [this branch](https://github.com/penpot/penpot/tree/niwinz-poc-plugins) in the Penpot local code.
-Copy `penpot-plugins/docs/index.mustache` to `penpot/frontend/resources/templates/index.mustache`.
-
Run the penpot runtime with `npm start`.
Now you can go to penpot and see the `log` of this file `plugins-runtime/src/index.ts`.
diff --git a/libs/plugins-runtime/src/index.ts b/libs/plugins-runtime/src/index.ts
index 9268803..9698244 100644
--- a/libs/plugins-runtime/src/index.ts
+++ b/libs/plugins-runtime/src/index.ts
@@ -2,7 +2,7 @@ import 'ses';
import './lib/plugin-modal';
import { ɵloadPlugin } from './lib/load-plugin';
-import { setFileState, setPageState } from './lib/api';
+import { setFileState, setPageState, setSelection } from './lib/api';
repairIntrinsics({
evalTaming: 'unsafeEval',
@@ -31,4 +31,11 @@ export function initialize(api: any) {
setFileState(file);
});
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ api.addListener('plugin-selection', 'selection', (selection: any) => {
+ console.log('Selection Changed:', selection);
+
+ setSelection(selection.linked_map.head?.uuid);
+ });
}
diff --git a/libs/plugins-runtime/src/lib/api/index.ts b/libs/plugins-runtime/src/lib/api/index.ts
index f0597c4..07240a8 100644
--- a/libs/plugins-runtime/src/lib/api/index.ts
+++ b/libs/plugins-runtime/src/lib/api/index.ts
@@ -4,7 +4,7 @@ import z from 'zod';
type Callback = (message: T) => void;
-const validEvents = ['pagechange', 'filechange'] as const;
+const validEvents = ['pagechange', 'filechange', 'selectionchange'] as const;
let uiMessagesCallbacks: Callback[] = [];
@@ -15,6 +15,8 @@ let pageState = {} as any;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let fileState = {} as any;
+let selection: null | string = null;
+
const eventListeners: Map[]> = new Map();
window.addEventListener('message', (event) => {
@@ -40,6 +42,16 @@ export function setFileState(file: unknown) {
triggerEvent('filechange', file);
}
+export function setSelection(selectionId: string) {
+ if (selectionId === selection) {
+ return;
+ }
+
+ selection = selectionId;
+
+ triggerEvent('selectionchange', selectionId);
+}
+
export function createApi() {
const closePlugin = () => {
if (modal) {
@@ -108,6 +120,9 @@ export function createApi() {
getPageState: () => {
return pageState;
},
+ getSelection: () => {
+ return selection;
+ },
};
return penpot;