Skip to main content
mohan_vadivel
New Member
June 10, 2023
Solved

How to copy text from one node to other

  • June 10, 2023
  • 1 reply
  • 399 views

Hey everyone, I’m wondering is there is a way to copy the text from one node to other using plugin API, while preserving various fills, weights, typefaces in the range.

This topic has been closed for replies.
Best answer by mohan_vadivel

Okay this seem to be the way

async function copyText(nodeA: TextNode, nodeB: any) {
    // @ts-ignore - Load all fonts used in the range
    let allFontNames = nodeA.getRangeAllFontNames(0, nodeA.characters.length);
    await Promise.all(allFontNames.map(figma.loadFontAsync));

    // // copy Characters
    nodeB.characters = nodeA.characters;

    let prop = [
        "fontSize",
        "fontName",
        "textStyleId",
        "fontWeight",
        "textDecoration",
        "textCase",
        "lineHeight",
        "letterSpacing",
        "listOptions",
        "indentation",
        "hyperlink",
        "fills",
        "fillStyleId",
    ];

    //@ts-ignore - get range details
    let segments = nodeA.getStyledTextSegments(prop);

    // loop over the range and set the font details
    segments.forEach((seg: any) => {
        nodeB.setRangeFontSize(seg.start, seg.end, seg.fontSize);
        nodeB.setRangeFontName(seg.start, seg.end, seg.fontName);
        nodeB.setRangeHyperlink(seg.start, seg.end, seg.hyperlink);
        nodeB.setRangeListOptions(seg.start, seg.end, seg.listOptions);
        nodeB.setRangeIndentation(seg.start, seg.end, seg.indentation);

        if (seg.textStyleId) {
            nodeB.setRangeTextStyleId(seg.start, seg.end, seg.textStyleId);
        } else {
            nodeB.getRangeFontWeight(seg.start, seg.end, seg.fontWeight);
            nodeB.setRangeTextDecoration(seg.start, seg.end, seg.textDecoration);
            nodeB.setRangeTextCase(seg.start, seg.end, seg.textCase);
            nodeB.setRangeLineHeight(seg.start, seg.end, seg.lineHeight);
            nodeB.setRangeLetterSpacing(seg.start, seg.end, seg.letterSpacing);
        }

        seg.fillStyleId
            ? nodeB.setRangeFillStyleId(seg.start, seg.end, seg.fillStyleId)
            : nodeB.setRangeFills(seg.start, seg.end, seg.fills);
    });
}

1 reply

mohan_vadivel
mohan_vadivelAuthorSolution
New Member
June 10, 2023

Okay this seem to be the way

async function copyText(nodeA: TextNode, nodeB: any) {
    // @ts-ignore - Load all fonts used in the range
    let allFontNames = nodeA.getRangeAllFontNames(0, nodeA.characters.length);
    await Promise.all(allFontNames.map(figma.loadFontAsync));

    // // copy Characters
    nodeB.characters = nodeA.characters;

    let prop = [
        "fontSize",
        "fontName",
        "textStyleId",
        "fontWeight",
        "textDecoration",
        "textCase",
        "lineHeight",
        "letterSpacing",
        "listOptions",
        "indentation",
        "hyperlink",
        "fills",
        "fillStyleId",
    ];

    //@ts-ignore - get range details
    let segments = nodeA.getStyledTextSegments(prop);

    // loop over the range and set the font details
    segments.forEach((seg: any) => {
        nodeB.setRangeFontSize(seg.start, seg.end, seg.fontSize);
        nodeB.setRangeFontName(seg.start, seg.end, seg.fontName);
        nodeB.setRangeHyperlink(seg.start, seg.end, seg.hyperlink);
        nodeB.setRangeListOptions(seg.start, seg.end, seg.listOptions);
        nodeB.setRangeIndentation(seg.start, seg.end, seg.indentation);

        if (seg.textStyleId) {
            nodeB.setRangeTextStyleId(seg.start, seg.end, seg.textStyleId);
        } else {
            nodeB.getRangeFontWeight(seg.start, seg.end, seg.fontWeight);
            nodeB.setRangeTextDecoration(seg.start, seg.end, seg.textDecoration);
            nodeB.setRangeTextCase(seg.start, seg.end, seg.textCase);
            nodeB.setRangeLineHeight(seg.start, seg.end, seg.lineHeight);
            nodeB.setRangeLetterSpacing(seg.start, seg.end, seg.letterSpacing);
        }

        seg.fillStyleId
            ? nodeB.setRangeFillStyleId(seg.start, seg.end, seg.fillStyleId)
            : nodeB.setRangeFills(seg.start, seg.end, seg.fills);
    });
}