# 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="../component-definition/manifest" %}
[manifest](https://docs.appmixer.com/6.0/v4.2/component-definition/manifest)
{% 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 selected</p><p><code>@checked</code> <em>- the component is deselected</em></p><p><code>@running</code> <em>- the flow is in a running state</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    | Contains a label of the component. |
| icon                        | image   | Contains an icon of the component. |
| 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',
                        },
                    },
                },
            },
        },
    },
};
```

![](https://4112778861-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LATDgYqVMe0hChW7efU%2F-MGHzNxmKor0ubNi5M84%2F-MGJXPh22gMASTxm7Jpp%2FScreenshot%202020-09-03%20at%2022.07.51.png?alt=media\&token=d5700d21-4f9b-46c1-bd3b-a64d0cf46df1)
