# Custom Component Shapes

### Usage

Shape registration in the Appmixer SDK:

```
var appmixer = new Appmixer({
    componentShapes: {
        action: myCustomComponentShape,
        trigger: myCustomComponentShape,
        myUniqueShape: myCustomComponentShape
    },
});
```

Use "action" and "trigger" keys to override defaults. You can define a custom shape for any component in the system, shape reference in a component manifest looks like this:

```
{
    shape: "myUniqueShape"
}
```

Built-in shapes are `action`, `trigger`, `actionVertical` and `triggerVertical`.

{% content-ref url="/pages/-LATDlWLofGff8LyImup" %}
[Manifest](/6.0/v4.1/component-definition/manifest.md)
{% endcontent-ref %}

### Definition

| Key                      | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `options.updateCallback` | An optional method called before the component is updated. Accepts `element` argument.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `attributes`             | Element attributes, see:  [jointjs.dia.Cell.define](https://resources.jointjs.com/docs/jointjs/v3.2/joint.html#dia.Cell.define)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `states`                 | <p>Definition for particular states of the component. The object structure is the same as the current scope <em>(except for the "states" entry)</em>.</p><p></p><p><code>@active</code><em>- the component is being modified</em></p><p><code>@invalid</code><em>- the component configuration is invalid</em></p><p><code>@referenced</code><em>- the component is highlighted</em></p><p><code>@unchecked</code><em>- the</em> component is unchecked</p><p><code>@checked</code><em>- the component is checked</em></p><p><code>@running</code><em>- the flow is in a running state</em></p><p><code>@selected</code><em>- the component is selected</em></p> |
| `ports.attributes`       | [P](https://resources.jointjs.com/docs/jointjs/v3.2/joint.html#dia.Element.ports.interface)orts attributes of [joint.dia.Element.ports.interface](https://resources.jointjs.com/docs/jointjs/v3.2/joint.html#dia.Element.ports.interface)                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `ports.states`           | <p>Definition for particular states of individual ports.</p><p>The object structure is the same as the current scope <em>(except for the "states" entry)</em>.</p><p></p><p><code>@connected</code> <em>- the port is connected</em> </p>                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `link.attributes`        | Link attributes, see: [jointjs.dia.Link](https://resources.jointjs.com/docs/jointjs/v3.2/joint.html#dia.Link)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |

#### Special selectors

Dynamic properties of the component, such as label and icon, are mapped to optional selectors in the markup.

| Selector                    | tagName | Description              |
| --------------------------- | ------- | ------------------------ |
| label                       | text    | Component label.         |
| icon                        | image   | Component icon.          |
| element-halo-copy-tooltip   | title   | "Copy" button tooltip.   |
| element-halo-cut-tooltip    | title   | "Cut" button tooltip.    |
| element-halo-remove-tooltip | title   | "Remove" button tooltip. |

#### Special attributes

| Key     | Value      | Description                        |
| ------- | ---------- | ---------------------------------- |
| `event` | `"remove"` | The entry acts as a remove button. |

```
var myCustomComponentShape = {
    attributes: {
        size: { height: 60, width: 60 },
        markup: [{
            tagName: 'rect',
            selector: 'body',
        }, {
            tagName: 'text',
            selector: 'label'
        }, {
            tagName: 'image',
            selector: 'icon',
        }],
        attrs: {
            body: {
                event: 'remove', // Click on the "body" will remove the element
                refWidth: '100%',
                refHeight: '100%',
                stroke: 'black',
                strokeWidth: '4px',
                fill: 'white',
            },
            label: {
                ref: 'body',
                textAnchor: 'middle',
                refX: 0.5,
                refY: '100%',
                refY2: 12,
                fill: 'black',
                fontFamily: 'Helvetica, Arial, sans-serif',
            },
            icon: {
                ref: 'body',
                refX: 0.5,
                refY: 0.5,
                xAlignment: 'middle',
                yAlignment: 'middle',
                height: 30,
                width: 30,
            },
        },
    },
    ports: {
        attributes: {
            in: {
                attrs: {
                    '.port-label': {
                        fontFamily: 'Helvetica, Arial, sans-serif',
                        fontSize: 12,
                    },
                },
            },
            out: {
                attrs: {
                    '.port-label': {
                        fontFamily: 'Helvetica, Arial, sans-serif',
                        fontSize: 12,
                    },
                },
            },
        },
    },
    link: {
        attributes: {
            router: {
                name: 'metro',
            },
        },
        attrs: {
            line: {
                event: "remove", // Click on the line will remove the link
            },
        },
    },
    states: {
        '@active': {
            attributes: {
                attrs: {
                    body: {
                        stroke: 'blue',
                    },
                },
            },
            link: {
                attributes: {
                    attrs: {
                        line: {
                            stroke: 'blue',
                        },
                    },
                },
            },
        },
    },
};
```

![](/files/-MGJXPh22gMASTxm7Jpp)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.appmixer.com/6.0/v4.1/customizing-ui/custom-component-shapes.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
