Interface Penpot

These are methods and properties available on the penpot global object.

interface Penpot {
    ui: {
        open: ((name: string, url: string, options?: {
            width: number;
            height: number;
        }) => void);
        sendMessage: ((message: unknown) => void);
        onMessage: (<T>(callback: ((message: T) => void)) => void);
    };
    utils: ContextUtils;
    closePlugin: (() => void);
    on<T>(type: T, callback: ((event: EventsMap[T]) => void), props?: {
        [key: string]: unknown;
    }): symbol;
    off(listenerId: symbol): void;
    root: null | Shape;
    currentFile: null | File;
    currentPage: null | Page;
    viewport: Viewport;
    history: HistoryContext;
    library: LibraryContext;
    fonts: FontsContext;
    currentUser: User;
    activeUsers: ActiveUser[];
    theme: Theme;
    selection: Shape[];
    shapesColors(shapes: Shape[]): (Color & ColorShapeInfo)[];
    replaceColor(shapes: Shape[], oldColor: Color, newColor: Color): void;
    uploadMediaUrl(name: string, url: string): Promise<ImageData>;
    uploadMediaData(name: string, data: Uint8Array, mimeType: string): Promise<ImageData>;
    group(shapes: Shape[]): null | Group;
    ungroup(group: Group, ...other: Group[]): void;
    createRectangle(): Rectangle;
    createBoard(): Board;
    createEllipse(): Ellipse;
    createPath(): Path;
    createBoolean(boolType: BooleanType, shapes: Shape[]): null | Boolean;
    createShapeFromSvg(svgString: string): null | Group;
    createText(text: string): null | Text;
    generateMarkup(shapes: Shape[], options?: {
        type?: "html" | "svg";
    }): string;
    generateStyle(shapes: Shape[], options?: {
        type?: "css";
        withPrelude?: boolean;
        includeChildren?: boolean;
    }): string;
    openViewer(): void;
    createPage(): Page;
    openPage(page: Page): void;
    alignHorizontal(shapes: Shape[], direction: "center" | "left" | "right"): void;
    alignVertical(shapes: Shape[], direction: "center" | "top" | "bottom"): void;
    distributeHorizontal(shapes: Shape[]): void;
    distributeVertical(shapes: Shape[]): void;
    flatten(shapes: Shape[]): Path[];
}

Hierarchy

  • Omit<Context, "addListener" | "removeListener">
    • Penpot

Properties

ui: {
    open: ((name: string, url: string, options?: {
        width: number;
        height: number;
    }) => void);
    sendMessage: ((message: unknown) => void);
    onMessage: (<T>(callback: ((message: T) => void)) => void);
}

Type declaration

  • open: ((name: string, url: string, options?: {
        width: number;
        height: number;
    }) => void)

    Opens the plugin UI. It is possible to develop a plugin without interface (see Palette color example) but if you need, the way to open this UI is using penpot.ui.open. There is a minimum and maximum size for this modal and a default size but it's possible to customize it anyway with the options parameter.

    penpot.ui.open('Plugin name', 'url', {width: 150, height: 300});
    
      • (name, url, options?): void
      • Parameters

        • name: string

          title of the plugin, it'll be displayed on the top of the modal

        • url: string

          of the plugin

        • Optionaloptions: {
              width: number;
              height: number;
          }

          height and width of the modal.

          • width: number
          • height: number

        Returns void

  • sendMessage: ((message: unknown) => void)

    Sends a message to the plugin UI.

    this.sendMessage({ type: 'example-type', content: 'data we want to share' });
    
      • (message): void
      • Parameters

        • message: unknown

          content usually is an object

        Returns void

  • onMessage: (<T>(callback: ((message: T) => void)) => void)

    This is usually used in the plugin.ts file in order to handle the data sent by our plugin

    penpot.ui.onMessage((message) => {if(message.type === 'example-type' { ...do something })});
    
      • <T>(callback): void
      • Type Parameters

        • T

        Parameters

        • callback: ((message: T) => void)

          A function that will be called whenever a message is received. The function receives a single argument, message, which is of type T.

            • (message): void
            • Parameters

              • message: T

              Returns void

        Returns void

Provides access to utility functions and context-specific operations.

closePlugin: (() => void)

Closes the plugin. When this method is called the UI will be closed.

penpot.closePlugin();
root: null | Shape

The root shape in the current Penpot context. Requires content:read permission.

const rootShape = context.root;
console.log(rootShape);
currentFile: null | File

Retrieves file data from the current Penpot context. Requires content:read permission.

Returns the file data or null if no file is available.

const fileData = context.currentFile;
console.log(fileData);
currentPage: null | Page

The current page in the Penpot context. Requires content:read permission.

const currentPage = context.currentPage;
console.log(currentPage);
viewport: Viewport

The viewport settings in the Penpot context.

const viewportSettings = context.viewport;
console.log(viewportSettings);

Context encapsulating the history operations

const historyContext = context.history;
console.log(historyContext);

The library context in the Penpot context, including both local and connected libraries. Requires library:read permission.

const libraryContext = context.library;
console.log(libraryContext);

The fonts context in the Penpot context, providing methods to manage fonts. Requires content:read permission.

const fontsContext = context.fonts;
console.log(fontsContext);
currentUser: User

The current user in the Penpot context. Requires user:read permission.

const currentUser = context.currentUser;
console.log(currentUser);
activeUsers: ActiveUser[]

An array of active users in the Penpot context. Requires user:read permission.

const activeUsers = context.activeUsers;
console.log(activeUsers);
theme: Theme

The current theme (light or dark) in Penpot.

const currentTheme = context.theme;
console.log(currentTheme);
selection: Shape[]

The currently selected shapes in Penpot. Requires content:read permission.

const selectedShapes = context.selection;
console.log(selectedShapes);

Methods

  • Adds an event listener for the specified event type. Subscribing to events requires content:read permission.

    The following are the posible event types:

    • pagechange: event emitted when the current page changes. The callback will receive the new page.
    • shapechange: event emitted when the shape changes. This event requires to send inside the props object the shape that will be observed. For example:
    // Observe the current selected shape
    penpot.on('shapechange', (shape) => console.log(shape.name), { shapeId: penpot.selection[0].id });
    • selectionchange: event emitted when the current selection changes. The callback will receive the list of ids for the new selection
    • themechange: event emitted when the user changes its theme. The callback will receive the new theme (currentlly: either dark or light)
    • documentsaved: event emitted afther the document is saved in the backend.

    Type Parameters

    Parameters

    • type: T

      The event type to listen for.

    • callback: ((event: EventsMap[T]) => void)

      The callback function to execute when the event is triggered.

        • (event): void
        • Parameters

          Returns void

    • Optionalprops: {
          [key: string]: unknown;
      }

      The properties for the current event handler. Only makes sense for specific events.

      • [key: string]: unknown

    Returns symbol

    the listener id that can be used to call off and cancel the listener

    penpot.on('pagechange', () => {...do something}).
    
  • Removes an event listener for the specified event type.

    Parameters

    • listenerId: symbol

      the id returned by the on method when the callback was set

    Returns void

    const listenerId = penpot.on('contentsave', () => console.log("Changed"));
    penpot.off(listenerId);
  • Retrieves colors applied to the given shapes in Penpot. Requires content:read permission.

    Parameters

    Returns (Color & ColorShapeInfo)[]

    Returns an array of colors and their shape information.

    const colors = context.shapesColors(shapes);
    console.log(colors);
  • Replaces a specified old color with a new color in the given shapes. Requires content:write permission.

    Parameters

    Returns void

    context.replaceColor(shapes, oldColor, newColor);
    
  • Uploads media to Penpot and retrieves its image data. Requires content:write permission.

    Parameters

    • name: string

      The name of the media.

    • url: string

      The URL of the media to be uploaded.

    Returns Promise<ImageData>

    Returns a promise that resolves to the image data of the uploaded media.

    const imageData = await context.uploadMediaUrl('example', 'https://example.com/image.jpg');
    console.log(imageData);

    // to insert the image in a shape we can do
    const board = penpot.createBoard();
    const shape = penpot.createRectangle();
    board.appendChild(shape);
    shape.fills = [{ fillOpacity: 1, fillImage: imageData }];
  • Uploads media to penpot and retrieves the image data. Requires content:write permission.

    Parameters

    • name: string

      The name of the media.

    • data: Uint8Array

      The image content data

    • mimeType: string

    Returns Promise<ImageData>

    Returns a promise that resolves to the image data of the uploaded media.

    const imageData = await context.uploadMediaData('example', imageData, 'image/jpeg');
    console.log(imageData);
  • Groups the specified shapes. Requires content:write permission.

    Parameters

    • shapes: Shape[]

      An array of shapes to group.

    Returns null | Group

    Returns the newly created group or null if the group could not be created.

    const penpotShapesArray = penpot.selection;
    penpot.group(penpotShapesArray);
  • Ungroups the specified group. Requires content:write permission.

    Parameters

    • group: Group

      The group to ungroup.

    • Rest...other: Group[]

      Additional groups to ungroup.

    Returns void

    const penpotShapesArray = penpot.selection;
    // We need to make sure that something is selected, and if the selected shape is a group,
    if (selected.length && penpot.utils.types.isGroup(penpotShapesArray[0])) {
    penpot.group(penpotShapesArray[0]);
    }
  • Use this method to create the shape of a rectangle. Requires content:write permission.

    Returns Rectangle

    const shape = penpot.createRectangle();
    // just change the values like this
    shape.name = "Example rectangle";

    // for solid color
    shape.fills = [{ fillColor: "#7EFFF5" }];
    // for linear gradient color
    shape.fills = [{
    fillColorGradient: {
    "type": "linear",
    "startX": 0.5,
    "startY": 0,
    "endX": 0.5,
    "endY": 1,
    "width": 1,
    "stops": [
    {
    "color": "#003ae9",
    "opacity": 1,
    "offset": 0
    },
    {
    "color": "#003ae9",
    "opacity": 0,
    "offset": 1
    }
    ]
    }
    }];
    // for a image fill
    const imageData = await context.uploadMediaUrl('example', 'https://example.com/image.jpg');
    shape.fills = [{ fillOpacity: 1, fillImage: imageData }];

    shape.borderRadius = 8;
    shape.strokes = [
    {
    strokeColor: "#2e3434",
    strokeStyle: "solid",
    strokeWidth: 2,
    strokeAlignment: "center",
    },
    ];
  • Use this method to create a board. This is the first step before anything else, the container. Requires content:write permission. Then you can add a gridlayout, flexlayout or add a shape inside the board. Just a heads-up: board is a board in Penpot UI.

    Returns Board

    const board = penpot.createBoard();

    // to add grid layout
    board.addGridLayout();
    // to add flex layout
    board.addFlexLayout();

    // to create a shape inside the board
    const shape = penpot.createRectangle();
    board.appendChild(shape);
  • Use this method to create the shape of a ellipse. Requires content:write permission.

    Returns Ellipse

    const shape = penpot.createEllipse();
    // just change the values like this
    shape.name = "Example ellipse";

    // for solid color
    shape.fills = [{ fillColor: "#7EFFF5" }];
    // for linear gradient color
    shape.fills = [{
    fillColorGradient: {
    "type": "linear",
    "startX": 0.5,
    "startY": 0,
    "endX": 0.5,
    "endY": 1,
    "width": 1,
    "stops": [
    {
    "color": "#003ae9",
    "opacity": 1,
    "offset": 0
    },
    {
    "color": "#003ae9",
    "opacity": 0,
    "offset": 1
    }
    ]
    }
    }];
    // for a image fill
    const imageData = await context.uploadMediaUrl('example', 'https://example.com/image.jpg');
    shape.fills = [{ fillOpacity: 1, fillImage: imageData }];

    shape.strokes = [
    {
    strokeColor: "#2e3434",
    strokeStyle: "solid",
    strokeWidth: 2,
    strokeAlignment: "center",
    },
    ];
  • Use this method to create a path. Requires content:write permission.

    Returns Path

    const path = penpot.createPath();
    path.name = "My path";

    // for solid color
    path.fills = [{ fillColor: "#7EFFF5" }];
  • Creates a Boolean shape based on the specified boolean operation and shapes. Requires content:write permission.

    Parameters

    • boolType: BooleanType

      The type of boolean operation ('union', 'difference', 'exclude', 'intersection').

    • shapes: Shape[]

      An array of shapes to perform the boolean operation on.

    Returns null | Boolean

    Returns the newly created Boolean shape resulting from the boolean operation.

    const booleanShape = context.createBoolean('union', [shape1, shape2]);
    
  • Creates a Group from an SVG string. Requires content:write permission.

    Parameters

    • svgString: string

      The SVG string representing the shapes to be converted into a group.

    Returns null | Group

    Returns the newly created Group containing the shapes from the SVG.

    const svgGroup = context.createShapeFromSvg('<svg>...</svg>');
    
  • Creates a Text shape with the specified text content. Requires content:write permission.

    Parameters

    • text: string

      The text content for the Text shape.

    Returns null | Text

    Returns the new created shape, if the shape wasn't created can return null.

    const board = penpot.createBoard();
    let text;
    text = penpot.createText();
    // just change the values like this
    text.growType = 'auto-height';
    text.fontFamily = 'Work Sans';
    text.fontSize = '12';
    text.fills = [{fillColor: '#9f05ff', fillOpacity: 1}];
    text.strokes = [{strokeOpacity: 1, strokeStyle: 'solid', strokeWidth: 2, strokeColor: '#deabff', strokeAlignment: 'outer'}];
    board.appendChild(text);
  • Generates markup for the given shapes. Requires content:read permission

    Parameters

    • shapes: Shape[]
    • Optionaloptions: {
          type?: "html" | "svg";
      }
      • Optionaltype?: "html" | "svg"

    Returns string

    const markup = context.generateMarkup(shapes, { type: 'html' });
    console.log(markup);
  • Generates styles for the given shapes. Requires content:read permission

    Parameters

    • shapes: Shape[]
    • Optionaloptions: {
          type?: "css";
          withPrelude?: boolean;
          includeChildren?: boolean;
      }
      • Optionaltype?: "css"
      • OptionalwithPrelude?: boolean
      • OptionalincludeChildren?: boolean

    Returns string

    const styles = context.generateStyle(shapes, { type: 'css' });
    console.log(styles);
  • Opens the viewer section. Requires content:read permission.

    Returns void

  • Creates a new page. Requires content:write permission.

    Returns Page

  • Changes the current open page to given page. Requires content:read permission.

    Parameters

    • page: Page

      the page to open

    Returns void

    context.openPage(page);
    
  • Aligning will move all the selected layers to a position relative to one of them in the horizontal direction.

    Parameters

    • shapes: Shape[]

      to align

    • direction: "center" | "left" | "right"

      where the shapes will be aligned

    Returns void

  • Aligning will move all the selected layers to a position relative to one of them in the vertical direction.

    Parameters

    • shapes: Shape[]

      to align

    • direction: "center" | "top" | "bottom"

      where the shapes will be aligned

    Returns void

  • Distributing objects to position them horizontally with equal distances between them.

    Parameters

    • shapes: Shape[]

      to distribute

    Returns void

  • Distributing objects to position them vertically with equal distances between them.

    Parameters

    • shapes: Shape[]

      to distribute

    Returns void

  • Converts the shapes into Paths. If the shapes are complex will put together all its paths into one.

    Parameters

    • shapes: Shape[]

      to flatten

    Returns Path[]