Skip to main content

Reactions: Make prototype connections editable via API

  • January 27, 2021
  • 6 replies
  • 2352 views

Will_Berger

It would be super powerful if reactions could be created or modified by plugins, so I’m curious why it’s read-only.

This topic has been closed for replies.

6 replies

Mr.Biscuit

Yeah, I don’t understand this read-only [Reaction { action: Action, trigger: Trigger }] neither, I even tried to set the action & trigger which is not read-only, but it gives this "TypeError: 'action' is read-only" error at run time 😭


Sean_Rice2

100% agreed! I was working on a plugin to standardize our animation timings for our design system. Got all the way to the end of it, but got a “There’s no setter for this property” error.

Here’s my code. Figma Genie! Please make this work!

export async function setTransitions(transition) {

    const page = figma.currentPage;
    const selection = page.selection;
    let checkTransitions = [];

    // Get our list of nodes within the selection that have transitions
    for (const node of selection){
        
        if (node.type == "GROUP" || node.type == "COMPONENT_SET" || node.type == "COMPONENT" || node.type == "FRAME" || node.type == "INSTANCE"){
            checkTransitions = node.findAll( (thisNode) => { 
                if (thisNode.type != "SLICE" && thisNode.type != "GROUP" && thisNode.type != "COMPONENT_SET"){
                    if ( thisNode.reactions.length >0 ) {
                        return true;
                    }
                }
                return false;
            });
        }
        if (node.type != "SLICE" && node.type != "GROUP" && node.type != "COMPONENT_SET"){
            if ( node.reactions.length >0 ) {
                checkTransitions.push(node);
            }
        }
    }

    // Set the transitions on every selected node -> reaction
    for (const node of checkTransitions){
        let newReactions = [];
        for (const reaction of node.reactions){
            if(reaction.action.type == "NODE"){
                let action;
                if( reaction.action.transition.type != "DISSOLVE" && reaction.action.transition.type.indexOf("ANIMATE")<0 ){
                    action = <Action>{
                        type: "NODE",
                        destinationId: reaction.action.destinationId,
                        navigation: reaction.action.navigation,
                        preserveScrollPosition: reaction.action.preserveScrollPosition,
                        transition: <DirectionalTransition>{
                            type: reaction.action.transition.type,
                            duration: transitions[transition].duration,
                            easing: transitions[transition].easing,
                            direction: reaction.action.transition.direction,
                            matchLayers: reaction.action.transition.matchLayers,
                        },
                        overlayRelativePosition: (typeof(reaction.action.overlayRelativePosition)==="undefined"?null:reaction.action.overlayRelativePosition),
                    }
                } else {
                    action = <Action>{
                        type: "NODE",
                        destinationId: reaction.action.destinationId,
                        navigation: reaction.action.navigation,
                        preserveScrollPosition: reaction.action.preserveScrollPosition,
                        transition: <SimpleTransition>{
                            type: reaction.action.transition.type,
                            duration: transitions[transition].duration,
                            easing: transitions[transition].easing,
                        },
                        overlayRelativePosition: (typeof(reaction.action.overlayRelativePosition)==="undefined"?null:reaction.action.overlayRelativePosition),
                    }
                }
                newReactions.push({action: action, trigger: reaction.trigger });
            }
        }
        node.reactions = newReactions; // This line gives the "no setter" error
    }
}


Will_Berger

I also started building a plugin to generate a card sort prototype for concept user testing. Realized it was read-only, and had to scrap everything.


ntfromchicago

With the new addition of flows, the ability to programmatically set these would be great.


Pantelis_Panayiotou

Trying also to get destinationId from Action but it won’t work. Any workarounds to safely get the destinationId or any other property figma doesnt expose?


Will_Berger

Looks like it’s available now! Blog · Figma Developers


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings