← Index Contents

Counter

Build a very simple Typescene Web app using the steps below.

Setup

In this guide, we’ll build a very simple app to demonstrate the basics concepts of Typescene Activities and Views. We’ll only need to write a few lines of code to fulfill the following requirements:

  • The app should show a ‘card’ with a title and the main UI.
  • On this card, the app should show a number (count).
  • The app should show an ‘Up’ button to increase the count, and a ‘Down’ button to decrease the count.

Tip: This project can be made to work with both TypeScript and JavaScript (using Babel to transpile ES6). Set your preference below:

TypeScriptJavaScript (ES6)

As the foundation for our mini-project, we’ll use the output of the create-typescene-webapp CLI tool. Refer to this guide for instructions.

The following command creates a new folder and installs all of the required dependencies:

npx create-typescene-webapp counter --jsx
npx create-typescene-webapp counter --jsx --js

Source files can be edited using any editor that can save plain text files, but an IDE or editor that is optimized for TypeScript can speed up your workflow significantly—even if you are not using TypeScript for your own code. Microsoft VS Code is an excellent choice.

You can also install the Typescene Snippets extension in Visual Studio Code for a quicker way to insert common class definitions.


Activity

In a Typescene application, Activities represent the application state (i.e. what the user is currently ‘working on’), and contain event handlers for the associated view.

In this case, our activity needs to keep track of the current counter value as a single number. We’ll also need to provide methods to increase and decrease this number.

A MainActivity file is already included in the output generated by create-typescene-webapp. Find the src/activities/main/activity.ts src/activities/main/activity.js file, and open it in your editor.

Change the class code (everything except the import lines) to the following:

TypeScriptJavaScript

export default class MainActivity
  extends PageViewActivity.with(view) {
  path = "/";

  counter = 0;

  countUp() { this.counter++ }
  countDown() { this.counter-- }
}
export default class MainActivity
  extends PageViewActivity.with(view) {
  constructor() {
    super();
    this.path = "/";
    this.count = 0;
  }

  countUp() { this.count++ }
  countDown() { this.count-- }
}

That’s all. In the view below, we’ll display the value of the counter property directly, and link the countUp() and countDown() methods to two separate buttons.

Note: Event handlers such as the methods above actually receive the event object itself as a single argument. This can be used to find out more information about the event and its source UI component. However since we’re not using this event data at all, we can simply leave out this parameter for now.


View

The only other file we’ll need to change is src/activities/main/view.tsx src/activities/main/view.jsx.

Typescene provides two options for writing view code:

  • Using JSX syntax, which looks like HTML but is actually compiled down by TypeScript or Babel into a series of function calls. In Typescene, these function calls result in a template that’s made up of standard components that are provided by Typescene itself.
  • Using standard JavaScript (TypeScript) syntax, to write the function calls yourself.

We’ll use JSX to create our view in this example. Change the content of the view.tsx view.jsx file to the following:

import { HMR } from "@typescene/webapp";
import JSX, { bind } from "typescene/JSX";

export default HMR.enableViewReload(
  module,
  <flowcell
    margin="auto"
    padding={16}
    dropShadow={0.5}
    borderRadius={8}
  >
    <row>
      <h3>Counter</h3>
    </row>
    <row>
      <label>The current count is {bind("counter")}</label>
    </row>
    <spacer />
    <row>
      <outlinebutton onClick="countUp()">
        Up
      </outlinebutton>
      <outlinebutton onClick="countDown()">
        Down
      </outlinebutton>
    </row>
  </flowcell>
);

What’s going on here?

  1. The call to HMR.enableViewReload sets up our view content in such a way that it can be replaced live in a browser when the given module’s source code is changed. This feature is called ‘hot module reloading’ or HMR, and is supported by Webpack, Parcel, and other build tools.

  2. The user interface (UI) itself is laid out within a ‘cell’ that’s resized automatically (i.e. a <flowcell> or UIFlowCell component), as a series of rows that stretch across the width of this cell (i.e. <row> or UIRow components). The visible elements within these rows are a heading, a label, and two buttons. Most views in Typescene apps are laid out in columns and rows exactly like this.

  3. Components such as the surrounding <flowcell> are styled using properties that are added directly to the JSX code – we don’t need to add any CSS to our application. However, Typescene does provide a way to style components using ‘style sets’ that can be defined separately and reused throughout the application. There’s also a way to ‘theme’ an entire app by defining colors and CSS styles for all components.

  4. To display the current counter value, we use a Binding that ‘binds’ itself to a property from the activity and starts watching for changes. When the activity’s property value changes, the view is updated automatically.

  5. The only way that the counter can be changed, is using the countUp() and countDown() methods of the activity. By adding event handlers to the view in the form of onClick properties, these methods are called automatically when one of our buttons is clicked (the Click event).

Summary

Here’s what we’ve learned so far:

  • Creating a new project folder is easy with the create-typescene-webapp CLI tool.
  • In a Typescene app, ‘Views’ define the visible part of the user interface, but do not include any code. We can use bindings and link to event handler methods of the ‘Activity’ to make the UI interactive.
  • ‘Activities’ represent the current application state, by exposing values that can be used by the view. Event handler methods are then used to update these values.

This is true even for larger applications, as activities and views grow in size and we add more of them: state and logic belongs in Activity classes, while the View is only used as a ‘template’. The activity can certainly be used to update view components directly, but in practice this is hardly ever necessary.

Next steps

Next, we’ll create a Todo-list app. Head over to First project to learn about Services and more complex UI components.