Creating your own UI extension points in Umbraco v14 - Part 5: Kinds

2 min read

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

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.


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.

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.

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 👋