In the last post we looked at how we can swap out our "quick action" button behavior whenever a button is clicked.
In this post we'll take a look at how we could allow someone to completely replace the button element with some other user control.
Element Extensions
To allow our actions to support a interchangeable elements we first need to update our manifest definition again.
export interface ManifestQuickAction extends ManifestElementAndApi<QuickActionElement, QuickActionApi> { type: 'quickAction'; meta: MetaQuickAction; } export interface QuickActionElement extends UmbControllerHostElement { manifest: UcManifestEntityQuickAction; api?: QuickActionApi; }
Here again we swap out the base interface and now extend from ManifestElementAndApi<>
. We also define a QuickActionElement
interface which lays out the required properties that any element used as a quick action must support. This interface, along with our previously defined API interface, are passed to the ManifestElementAndApi<>
interface as generic arguments.
If we take a look at the ManifestElementAndApi<>
interface we can see that our manifest now supports a couple of extra properties.
export interface ManifestElementAndApi<ElementType, ApiType> extends ManifestBase { element?: ElementLoaderProperty<ElementType>; elementName?: string; ... }
Default Element Updates
With our element interface defined, we can go back to our default button implementation and ensure this now implements our required interface.
@customElement("quick-action") export class QuickActionElement extends UmbElementMixin(LitElement) implements QuickActionElement { @property({ type: Object, attribute: false }) manifest!: ManifestQuickAction; @property({ type: Object, attribute: false }) api?: QuickActionApi; #onClick(e: Event) { this.api?.execute(); } render() { return html`<uui-button look=${this.manifest.meta.look ?? 'secondary'} @click=${this.#onClick}> ${this.manifest.meta.label} </uui-button>` } } export default QuickActionElement; declare global { interface HTMLElementTagNameMap { "quick-action": QuickActionElement; } }
Overriding the Default Element
With everything configured developers can now override the default button element by firstly creating their own component that implements our interface.
@customElement("my-quick-action") export class MyQuickActionElement extends UmbElementMixin(LitElement) implements QuickActionElement { @property({ type: Object, attribute: false }) manifest!: ManifestQuickAction; @property({ type: Object, attribute: false }) api?: QuickActionApi; #onClick(e: Event) { this.api?.execute(); } render() { return html`RENDER YOUR COMPONENT HERE` } } export default MyQuickActionElement; declare global { interface HTMLElementTagNameMap { "my-quick-action": MyQuickActionElement; } }
Then updating the manifest to use this component instead.
export const quickActionManifests: ManifestQuickAction[] = [ { type: 'quickAction', alias: 'Mb.QuickAction.SendEmail', name: 'Send Email Quick Action', weight: 200, element: MyQuickActionElement, api: SendEmailQuickActionApi, meta: { label: "Send Email", look: "primary" } }, { type: 'quickAction', alias: 'Mb.QuickAction.ChangeStatus', name: 'Change Status Quick Action', weight: 100, element: MyQuickActionElement, api: ChangeStatusQuickActionApi, meta: { label: "Change Status" } } ]
What's next?
In this post we've looked out how to allow developers to override the default element of an extension.
In the next post we'll take a look at how we can reduce some repetition in our manifest definitions by creating reusable 'kinds'.
Until then 👋
Top comments (0)