Creating your own UI extension points in Umbraco v14 - Part 5: Kinds
Tags: webdev, javascript, umbraco, extensions
Published: 2024-04-16 08:00:00

In the last posts in this series, we've looked at ways to allow developers to swap out behaviors and UI elements for our "quick action" feature.

![Quick Action Buttons](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6usoxczmfxg7tnf10m96.png)

In this post we'll take a look at how we can reduce some repetition in our manifest definitions by using 'kinds'.

## Kind Definitions

In Umbraco v14, kinds are essentially reusable, prepopulated manifest definitions, saving you from having to fill in all manifest properties for common use cases.

In our "quick actions" feature, we have two key button types, and we have a default button and API implementation so lets create two kinds that preconfigure these settings.

```javascript

export type QuickActionKind = ManifestKind<ManifestQuickAction> & ManifestBase;

export const kindManifests: Array<QuickActionKind> [
    {
        type: 'kind',
        alias: 'Mb.Kind.QuickAction.Primary',
        name: 'Primary Quick Action Kind',
        matchKind: 'primary',
        matchType: 'quickAction',
        manifest: {
            type: 'quickAction',
            kind: 'primary',
            element: QuickActionDefaultElement
            api: QuickActionDefaultApi,
            meta: {
                look: 'primary'
            }
        }
    },
    {
        type: 'kind',
        alias: 'Mb.Kind.QuickAction.Default',
        name: 'Default Quick Action Kind',
        matchKind: 'default',
        matchType: 'quickAction',
        manifest: {
            type: 'quickAction',
            kind: 'default',
            element: QuickActionDefaultElement
            api: QuickActionDefaultApi,
            meta: {
                look: 'secondary'
            }
        }
    }
]
```

Essentially we define a `QuickActionKind` kind type that extends `ManifestKind<ManifestQuickAction>` and `ManifestBase` and then create an array of implementations which state the `matchKind` and a `matchType` that our manifest `kind` and `type` attribute must be set to for this kind to apply.

Then, the `manifest` property defines a partially implemented `ManifestQuickAction` manifest. The values in this definition will automatically be copied over to any matching manifests.

## Registration

As with any manifest definitions, we must register them with the extensions registry.

```javascript
export const onInit: UmbEntryPointOnInit = (host, extensionRegistry) => {
    extensionRegistry.registerMany(kindManifests);
};
```
## Manifest Updates

With our kind manifests registered, we can now update our quick action manifests to use these kinds to prepopulate our properties for us.

```javascript
export const quickActionManifests: ManifestQuickAction[] = [
    {
        type: 'quickAction',
        kind: 'primary',
        alias: 'Mb.QuickAction.SendEmail',
        name: 'Send Email Quick Action',
        weight: 200,
        meta: {
            label: "Send Email"
        }
    },
    {
        type: 'quickAction',
        kind: 'default',
        alias: 'Mb.QuickAction.ChangeStatus',
        name: 'Change Status Quick Action',
        weight: 100,
        meta: {
            label: "Change Status"
        }
    }
]
```

Here we give each of our manifests a `kind` property value and remove the `element`, `api` and `meta.look` properties as these will now come directly from our kind definition.

## Optional Cleanup

Because we are now using kinds to give all our manifests some defaults, we could do a little bit of cleanup here. In the second post in this series, we defined our default element globally and set it as the default element on our `umb-extension-with-api-slot`. 

As all our definitions now come with a element defined, we could remove these and just use the values from our manifests.

## What's next?

In this post we've look at how we can use "kinds" to create reusable manifest definitions.

In the next post, we'll take a look at how we make our manifests control when an action should be displayed by using filters and conditions.

Until then 👋