A sample application with Aurelia UX

Posted on 2017-08-14 in Aurelia

This is a follow up to my Small comparison of ionic2 and Aurelia + Framework7 for hybrid mobile applications article where I compared ionic2 and Aurelia with Framework 7 for building an hybrid applications. At the time, Aurelia UX was not yet ready (and we were expecting a different, closed source project called Aurelia Interface). Now, Aurelia UX made huge process and I was able to write the sample application in it. I describe here how it went. The code is available on github with the other applications.

As a reminder, here are the features of the TODO application:

  • List all the saved todos (home page)
  • Edit an existing todo
  • Add a todo
  • Mark a todo as done on the home page. Done todos must have their title strike-through on the home page.

I wrote the application in TypeScript and CSS, since they are the languages Aurelia UX and its showcase application are written in. Here are screenshots of the result:

Page to list all TODOs Page to add or edit todo The menu of the application

I based my application on the Aurelia UX showcase app: I cloned this repo, remove the code I didn't need and started to add my code. It is structured like this:

  • An assets folder with the images and fonts
  • An aurelia_project folder that contains the configuration for the cli
  • A custom_typings folder for TypeScript type definitions
  • A scripts folder created by the cli for some useful scripts (eg require.js)
  • A src folder that contains the application in itself. It contains:
    • The main.ts file which is the entry point to the application
    • routes.ts to configure the routes of the application
    • CSS files common to all the application
    • app.ts, app.css and app.html which configure the layout of the page and configures the menu and the router
    • A models folder that contains type definition of the application for TypeScript
    • A pages folder which contains the HTML, JS and CSS code for each routes
    • A services folder that contains services for the application

Now that's done, let's take a look at the code. I won't detail the main.ts too much since it is very classic. I'll just point out to line 18:

.plugin('aurelia-ux')

This is where we enable Aurelia UX in our application. If we don't, we won't be able to use its tags and attributes in our application.

In the app.ts, we import AureliaUX from the aurelia-ux module and inject it into our application. If you look at the constructor, you'll see the first interesting piece:

constructor(private ux: AureliaUX) {
    ux.design.primary = MAIN_THEME.primary;
    ux.design.accent = MAIN_THEME.accent;

    this.showNavigationMenu = false;
}

Here is the definition of MAIN_THEME:

const MAIN_THEME = {
    primary: '#009688',
    accent: '#4CAF50',
};

We are using this to set the color of the style of our application. If you look at the corresponding CSS, you can see something like:

styles.header {
    background: ${$design.primary};
    color: ${$design.primaryForeground};
}

As you may guess, thanks to the design property of the AureliaUX object, our CSS code and our TypeScript code are linked. The content of ux.design.primary will replace all the occurrences of ${$design.primary} in the CSS. And the best part is: it is dynamic! If you change ux.design.primary in your application, the style will update to reflect it. You can test this by opening the hamburger menu and clicking on the Alternate theme check box. This will call the theme changed function to update the style of the application.

To use this feature in our HTML, we must:

  1. Require the CSS file with the ux hash:

    <require from="./app.css#ux"></require>
    
  2. Use styles.header as a custom attribute, like this:

    <header styles.header>
        <h1 styles.header-h1>${router.currentInstruction.config.navModel.title}</h1>
        <a styles.clickable target="_self" click.delegate="toggleNavigationMenu()">
            <i styles.header-burger class="fa fa-bars" aria-hidden="true"></i>
        </a>
    </header>
    

Simple and efficient, isn't?

Navigation in the application is handled by Aurelia's router. Since you are probably already familiar with it, I won't detail that here.

Lets take a look at the edit page. There isn't much in the TS code: we basically setup the validation (to know more about validation, see this article), rely on the storage service to load the TODO to edit (if we are editing an existing TODO) and save it in the cache. We also use this.router.navigateToRoute('list'); to navigate in the application.

The more interesting part is the HTML where I use tags defined by Aurelia UX. The form to add a TODO is located in a ux-form tag. I then use the custom tags to create:

  • The input for the title:

    <ux-input
                 placeholder="Title"
                 value.bind="todo.title & validate"
    ></ux-input>
    
  • The textarea:

    <ux-textarea
                  auto-resize
                  placeholder="Description"
                  value.bind="todo.description & validate"
    ></ux-textarea>
    
  • The done checkbox:

    <ux-field>
       <ux-checkbox checked.bind="todo.done">Done</ux-checkbox>
    </ux-field>
    
  • The save button:

    <ux-button type="raised" click.delegate="save()" disabled.bind="!canSave">Save</ux-button>
    

As you can see, they are simply custom elements and behave like any other custom elements would.

The list page is quite basic so I won't detail it. If you have questions, please leave a comment.

What I didn't test:

  • Building the application and sending it to my phone. I suspect this will be similar to what you can do with Framework 7 or ionic.
  • Using SCSS instead of CSS. I frankly have no idea how this would behave in conjuction with how you can interact with CSS inside Aurelia UX (things like ux.design.primary = MAIN_THEME.primary; in your JS and background: ${$design.primary}; in the CSS.

There is currently no documentation about Aurelia UX but the showcase app contains example for all the available components. You can clone the repo and launch it with npm install to install the dependencies and then au run to run it.

To conclude: I find the project promising. It's easy to work with, has some really nice features (such as the ability to have easy links between the code and the CSS). The look and feel of the application is great. The integration with Aurelia is perfect. It also looks a lot like ionic so developers used to this framework shouldn't be lost. They are however some downsides: this is still a work in progress and some components don't exist yet (eg select). I also found that the checkboxes are not always reliable. Some clicks where not taken into accounts. I don't know if this came from my browser (FireFox for desktop, I haven't tested on mobile) or from the way the check boxes are rendered (they are not real check boxes but divs so they can be styled correctly).

That's it for today. If you have a question or remark, please leave a comment below.