Skip to content
Lauri Rooden edited this page Aug 15, 2024 · 17 revisions

LiteJS UI – Size Buy Me A Tea

LiteJS UI is an old-school framework for high-quality web UIs, used on heavy-traffic websites since 2006.

  • Dependency-free, weighs around 25KB (+8KB polyfills for old browsers).
  • Written in ES5, compatible with all browsers (including IE5.5).
  • No transpiling/compiling/bundling headache, just write a working code.

It is part of LiteJS full-stack web framework, that is split into three main packages:
  • litejs for backend • @litejs/ui for UI • @litejs/cli command line tool.

In short — a UI has two layers: presentation and data.

  • Presentation layer includes templates, routed views, and bindings to data layer.
  • Data layer is a number of observable Arrays of observable Objects.

Build your first LiteJS app with in 5 minute Quick Start guide.

Examples

We believe that most web applications shouldn't require more than 100KB of code (HTML+js+CSS) to download.

Statements of work, project proposals and design briefs should explicitly and repeatedly call out performance as a primary goal.
“The goal of this project is to create a stunning, flexible, lightning-fast experience…”
-- Brad Frost "performance as design" 2013

Presentation layer

Developers abandoned XML for APIs long ago but still use it for UI code.
LiteJS uses indented CSS selectors for templates, making them familiar and efficient.

The goal is to include all essentials so you can focus on your app, not the stack.

  1. Templates.
  2. Plugins.
  3. Bindings.
  4. Views and Routes.

﹢ responsive design with breakpoints, keyboard events, touch gestures, translations, DOM quering (querySelector for IE5.5), 50+ shims.

1. Templates

Template can contain all your code to be a single-file Single-Page Application (SPA).

DOM-aware template engine converts templates directly to DOM nodes, parsing and rendering them in the browser without backend compilation.

source: my.ui becomes: my.html
h1 My list
ul.green.star
    li > a[href="#a"] Item A
    li
        a[href="#b"] Item B
footer
    button:disabled My button
<h1>My list</h1>
<ul class="green star">
    <li><a href="#a">Item A</a></li>
    <li><a href="#b">Item B</a></li>
</ul>
<footer>
    <button disabled>My button</button>
</footer>

Type, class, ID, and attribute selectors, along with shorthand pseudo-classes are supported.
Child combinators can be used, and omitting the tagName defaults to a div element.

2. Plugins

Plugins begin with % in templates.

  • %def [route,...] [route|file,...] - Define routes in other files and therid dependencies.
  • %el [name] - Create a new custom element.
  • %slot [name] - A placeholder for content, name is optional.
  • %view [name] [parent] - Organize views into a hierarchy with built-in router.
    • Accepts Level 1 URI Templates [RFC 6570][].
    • Views with name starting with # are containers without direct route.

3. Bindings

Bindings begin with ; in templates.

  • ;cls [className], [state] - Add/remove class based on state.
  • ;txt![content] - Add plain text to element.

Listener shorthand @click 'logout' is equal to ;on!'click','logout'.
Binding with ! after a name executes only once and does not update thereafter.

4. Views and Routes

Many developers believe that routing sucks, but it is actually one of the simplest aspects of single-page applications.

Routings don't even deserve a separate chapter; they are merely parameters of Views.

Views can be nested and have URL routing applied to it.

If a view name begins with the # symbol, it is a container for other views and does not have its own route. Other views are accessible by their name.

/   An end-of-line comment starts with a slash
/   ╭───────────────╼ plugin `%view` declares a new view
/   │    ╭──────────╼ name starting with `#` are without a route for structuce
/╭──┤ ╭──┴──╮ ╭─────╼ parent view name, `#` is <body> by default
%view #public #
.app
    h1 LiteJS app
    nav
        a[href="#home"] Home
        span |
        a[href="#user"] Users
        span |
        a[href="#about"] About
    / Default slot for content
    %slot
    .footer
      dt Bye
        dd
          / Named slot for other content
          %slot footer

/        ╭──────────╼ name is also a public route
/     ╭──┤ ╭─────┬──╼ parent view name
%view home #public
p Welcome to my page
p This all will be in default slot
dd[slot=footer] Something put to named slot

%view user #public
p List of users..

%view user/{userId} #public
p User {params.userId}

%view about #public
p This is about