Get all nodes that are red

Hi,

I would like to remove all the components that are red, is there a way to filter all the components based on their color ?

Thanks,

Antoine

1 Like

Of course, it’s super easy if you know the exact color, .

const redNodes = figma.findAll(node => node.fills.find(paint => paint.type === 'SOLID' && paint.r === 1 && paint.g === 0 && paint.b === 0))

Thanks for the answer, but I have another problem. I am trying to get the nodes of the components which are red inside of a pageNode but there are errors for node.fills.find() and redNodes.remove(), saying that:

TS2339: Property ‘fills’ does not exist on type ‘SceneNode’. Property ‘fills’ does not exist on type ‘SliceNode’.

And here is the code:

const pageNodeExport = figma.root.children.find(n => n.name === "Export") as PageNode
const redNodes = pageNodeExport.findAll(node => node.fills.find(paint => paint.type === 'SOLID' && paint.r === 1 && paint.g === 0 && paint.b === 0));
if (redNodes){
    redNodes.remove();
}

How can I solve this?

In simplest terms, this is TypeScript warning you about the fact that a specific property you are trying to access may not be present on the nodes depending on the type.

It’s a TypeScript error, which doesn’t mean your code is wrong, it means TypeScript thinks it’s wrong. It knows that findAll function and other similar functions can return all types of nodes (SceneNode), and it doesn’t know that your condition will only return objects of a specific type.

There are four ways to “fix” this:

  1. Use a simple condition to check if the node is the type you need: if (node.type === 'FRAME') { /* do something with a frame */ }

  2. But what if you only want to check a specific property and don’t care about node type? Use if ('children' in node) { /* do something with a node that has children */} — see documentation here.

  3. The outdated proper way (but still useful in some cases) is be to implement a function with the type predicate and make sure your object is indeed a FrameNode (or whatever other types you need). Example function:

    // Returns type predicate and true if node supports children
    function isFrameOrGroup(node: SceneNode):
    node is FrameNode | GroupNode {
      return node.type === 'FRAME' || type === 'GROUP'
    }
    

    Usage: if ( isFrameOrGroup(node) ) { /* do something */ }

    This was necessary before because node.type had no relation to the TypeScript types. Now TypeScript got smarter so this is not required if the method above is sufficient for your needs.

  4. If you know the type of objects you will be getting explicitly (and you are sure they won’t be different), you can make a type assertion: node as FrameNode.

    Both of these things are explained in the TypeScript docs: https://www.typescriptlang.org/docs/handbook/advanced-types.html

  5. For testing purposes, you can simply use // @ts-ignore comment above each line which you want TypeScript to ignore completely.

Alternatively, you can switch entirely to plain JavaScript if you don’t want to deal with typing issues. :slight_smile:

4 Likes