Skip to content

Specification note of rendering tags in Riot.js

karak edited this page Apr 17, 2018 · 1 revision

[WIP] Specification note of rendering tags in Riot.js

Templates

Expressions

A region between brackets {} is evaluated as a JavaScript expression.

Evaluation context, or this, is one of the followings:

  1. An instance of defining tag by default
  2. The closest parent when tags are nested
  3. A loop variable in "each" directives, and it inherits all the properties of the parent context.

And this.parent points the parent tag instance by default, this of the parent tag under loops, or null if the it is a root tag.

Note: these expressions may be preprocessed as script sections according to "riot.config."

Boolean attributes

Boolean attributes like "checked" of "input" will disappear when their value is falsy. Riot has a list of those attributes.

Class shorthand

Class definition is also defined by object map from the name to enabling flag.

For example:

<my-button>
  <button class={ btn: true, visible: opts.visible, 'btn-disabled': opts.disabled }>
	Submit
  </button>
</my-button>

Then, <my-button visible /> is rendered as <my-button><button class="visible">Submit</button></my-button>.

Partial use is allowed as:

<my-button>
  <button class="btn { visible: opts.visible, 'btn-disabled': opts.disabled }">
    Submit
  </button>
</my-button>

In fact, all the string properties accept this form (TODO: confirmation).

Class object expressions

TBD

Style object expressions

TBD

Directives

Some attributes and elements have special semantics.

"if" attributes

Switches existence.

An element doesn't render itself and its children when "if" is falsy.

"show" attributes

Switches visiblity.

An element has display: "" in its inline "style" if its "show" attribute is truthy, display: none otherwise.

"hide" attributes

Reverse to "show"

"each" attributes

Generate loops.

<my-list>
  <ul>
    <li each={ item in items }>
      { item.text }
    </li>
  </ul>
</my-list>

It has two forms: each={ items } and each={ item in items }.

Note: the former style is to be obsolete by v4.

See also above about its evaluation context.

"virtual" elements

<virtual> elements generate no actual elements but still work in templating. They are often used with "if" or "each" attributes keeping DOM structure.

"yield" elements

<yield> elements have a special role in transclusion. See the next section.

Transclusion

Elements under a nested tag are to replace <yield /> element in the tag when rendering it. This is called transclusion.

Multiple transclusions are provided by combinations of <yield to="name"> in nesting and <yield from="name" /> in tag definitions.

See above about its evaluation context.

See the following doc, especially for yield and loops.

http://riotjs.com/api/#-yielding-nested-html

Styles

Style sections are compiled to plain CSS styles and added to the global document when the tag is registered.

Scoped CSS, or ":scope" psuedo-class, can be used.

Note: Riot always uses its own implementations of scoped CSS.

Attributes

Riot allows to pose attributes in the root of a custom tag, while React and others not.

For example:

<app-menu role="navigation">
  <!-- contents are here -->
</app-menu>

Scripts

Script sections, sometimes called "onCreated" or "constructor", run once after the tag have been constructed.

Evaluation context, or this is an instance of the tag.

Tag instances

Riot creates an instance of tag when mounting, and keep it updated until unmounting it.

Note: React does it only if the component is a class.

See also the original document: http://riotjs.com/api/#tag-instance.

opts

The property "opts" is known as tag interface, main way to recieve parameters. It must be object mapping string keys to any types of values.

Elements and tags

Tag instance stores some elements and tags rendered during mount.

root

TBD

parent

TBD

Note: Don't confuse this with the loop context in expressions.

tags

Tag instance has "tags" property. It is an object which maps name to all the nested tags with the name. Mapped value is one tag instance or array of them if any. Note "tags" contains only direct children, not a child of the children.

See http://riotjs.com/api/#nested-tags.

This feature is to be obsolete by v4.

refs

Tag instance has "refs" property. It is an object which maps name to the nested elements only with the name as a value of the ref attribute. Nested tags also may have the attribute.

ids and names [obsolete]

And all of the values of "id" or "name" attributes stores the internal elements with them before riot v3.

Lifecycle methods

mount()

TBD

It triggers "before-mount" and "mount" events.

update()

Evaluate all the expressions again and reconstruct the element tree.

It triggers "update" and "updated" events.

This method accepts one optional parameter members of which are set to this before updating.

See http://riotjs.com/api/#updating.

unmount()

TBD.

This has one optional boolean argument to remove the root element from DOM tree.

It triggers "before-unmount" and "unmounted" events, and then removes all the event observers, actually calling off('*').

Observable methods

All of the functions are available of riot-observable: "on", "off", "one", and "trigger".

Lifecycle events

Riot fires following events in life of a tag: "update", "updated", "before-mount", "mount", "before-unmount", and "mount".

See http://riotjs.com/api/#events.

User-defined events

TBD

Mixin methods

mixin([name])

Retrieve the mixin with the name and applied its init methods to this instance. Global mixins are also applied implicitly before construction.

See http://riotjs.com/api/#mixins.

User-defined properties and methods

And it may have all of the user-defined properties including ones mixins may have added.

Avoid the names Riot reserves, described here and what start with underscore. See http://riotjs.com/api/#reserved-words.

DOM Events

Basically, Riot events are equivalent to those of native DOM which Riot assumes to meet the specifications of the DOM Level 3 Events.

Riot updates the closest parent tag automatically after all the listeners finish if any.

Event objects have two extra features:

  1. An "item" property storing loop variable under "each" loops.
  2. A "preventUpdate" property which allows you skip the following auto-updating by assigning false .

Miscellaneous

Custom element alternative

An root element of a tag has always "data-is" attribute with the name of the tag, even if no custom element feature is available. For example: <my-button/> is rendered as <my-button data-is="my-button"> or <div data-is="my-button"> fallen-back on legacy browsers, and CSS should work in both cases.

"data-is" was once "riot-tag" [obsolete].

Conventional names

  • Names of tags are always converted to lower-case.
  • Names of attributes are converted to lower-camel-case from snake-case in "opts".
  • Certain attributes like "src" is only assigned from the one with a "riot-" prefix.