Skip to content

Micro framework using the latest ECMAScript, HTML and CSS features to build apps

Notifications You must be signed in to change notification settings

homebots/elements

Repository files navigation

Elements

This is a microframework that tries to use the latest API's from HTML, Javascript and CSS to run web apps.

Using Custom elements and a few other features, like dependency injection, change detection and lifecycle hooks.

Lifecycle hooks

Every custome element can implement one of the following hooks: OnInit, OnDestroy, onChanges, OnBeforeCheck

Change detection

Every instance has its own change detection context, but when a component changes something, the change detection looks at all observed properties in that context and all children, starting from the root element.

This is to ensure that changes that affect the parent elements can also be checked.

As an alternative, change detection (via Zone.js) can be used as well.

Examples

A minimalistic todo app:

// app.component.ts
import { Component } from '@homebots/elements';

@Component({
  tag: 'todo-app',
  template: `
    <form (submit.stop)="this.addTask(newtask.value); newtask.value = ''">
      <input #newtask />
      <button type="submit">add</button>
    </form>
    <ul>
      <template *for="'task'" [of]="this.tasks">
        <li><input type="checkbox" (change.stop)="task.done = !task.done" [value]="task.done" /> {{ task.title }}</li>
      </template>
    </ul>
  `,
})
export class TodoApp extends HTMLElement {
  tasks = [];

  addTask(title: string) {
    return this.tasks.push({ done: false, title });
  }
}

Then bootstrap the application:

// index.ts
import { Bootstrap } from '@homebots/elements';
import './app.component.ts';

Bootstrap.createApplication();

Then finally put all together:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Todo</title>
    <script src="https://unpkg.com/reflect-metadata"></script>
    <script type="module" src="./index.ts"></script>
  </head>

  <body>
    <todo-app></todo-app>
  </body>
</html>

Syntax

Most of the syntax is shamelessly copied from Angular and Alpine.js:

<!-- bind an attribute -->
<div @class="this.dynamicClasses"></div>

<!-- bind a property -->
<div [innerText]="this.text"></div>

<!-- listening to events -->
<div (click)="this.onClick()"></div>

<!-- using references -->
<input #name />
<button (click)="name.focus()">click me</button>

<!-- conditional nodes -->
<template *if="this.showName" [else]="noname">Hello, John!</template>
<template #noname>Who are you?</template>

<!-- loops -->
<ul>
  <template *for="'name'" [of]="this.listOfNames">
    <li>{{name}}</li>
  </template>
</ul>

<!-- conditional classes -->
<p [class.highlight]="this.isTextHighlighted">Lorem ipsum</p>

Dependency Injection

// injectable class
@Injectable()
export class UserService {}

@Injectable()
export class AppService {
  // injected service
  @Inject() userService: UserService;

  // injected with symbol
  @Inject(ChangeDetector) userService: ChangeDetector;
}

Dependencies

The Reflect API for Typescript metadata.

<script src="https://unpkg.com/reflect-metadata"></script>

About

Micro framework using the latest ECMAScript, HTML and CSS features to build apps

Resources

Stars

Watchers

Forks

Packages

No packages published