🤖 Create an engaging chatbot from scratch and add it to your NativeScript app! Learn more at our webinar on March 28th.

NativeScript Core

Building UI Plugins using Composite Components

When writing a plugin that shows some UI, you can take different paths. One of the easiest of them is to use existing {N} components as building blocks for a more complex UI component (composite), i.e. no explicit calls to native APIs. Thus you can even sometimes avoid using platform-specific files (like *.ios.ts, *.android.ts ...).

Bootstrap Your Plugin

First things first - you start off from a regular plugin. You can check the Building Plugins article for reference.

Add UI bits

Let's say you want to build a simple meme generator component with three properties, which you can use like:

    <ui:Meme imageSource="~/images/nativescript.png" topText="ROCK" bottomText="ROLL" />

...and when used in an app it looks like:

You can implement this by creating two files:

  • meme.ts: Contains properties, the implementation logic, and loads the UI.
  • meme.xml: Contains the UI and data bindings.

In meme.ts, you need to declare a class with the name of the UI element that will be used in the app:

export class Meme extends GridLayout {
    constructor() {
        super();

        let innerComponent = builder.load(__dirname + '/meme.xml') as View;
        innerComponent.bindingContext = this;

        this.addChild(innerComponent);
    }
}

As you see, in the constructor, we load the UI from the meme.xml and set its bindingContext to this, so that we can bind the XML to the properties:

<GridLayout rows="auto,*, auto"> 
    <Label row="0" text="" fontSize="64" textWrap="true" 
        horizontalAlignment="center" verticalAlignment="top"></Label>

    <Image rowSpan="3" src="" verticalAlignment="stretch"></Image>

    <Label row="2" text="" fontSize="64" textWrap="true" 
        horizontalAlignment="center" verticalAlignment="bottom"></Label>
</GridLayout>

The properties themselves are declared and registered in the .ts like:

export const topTextProperty = new Property<Meme, string>({ name: "topText", defaultValue: undefined });
export const bottomTextProperty = new Property<Meme, string>({ name: "bottomText", defaultValue: undefined });
export const imageSourceProperty = new Property<Meme, string>({ name: "imageSource", defaultValue: undefined });

...

imageSourceProperty.register(Meme);
topTextProperty.register(Meme);
bottomTextProperty.register(Meme);

For more details and the full source code of the described meme sample, check the NativeScript ui-plugin sample repo.

Make Your Plugin Angular-Compatible

Having your UI plugin developed successfully you could easily make it Angular-compatible following the steps described in Supporting Angular in UI Plugins article.