Version 3.7.0
Security
Authentication
SubtleCrypto
Module System
New method Module.addPath
Module.addPath
allows to define path aliases to make imports more consistent. It supports the TypeScript compiler "paths" option.
New method Module.define
Module.define
can create new modules at runtime, for example to dynamically override file modules.
Widgets
CollectionView reveal with offset
beforeTextChange
Event System
Observables
Tabris now provides an implementation of the proposed Observable API. It has been integrated in to the event system so you can get observables for specific events (e.g. button.onSelect.subscribe(...)
), property values (via change events, e.g checkBox.onCheckedChanged.values.subscribe(...)
), or any object emitting Tabris.js change events (Observable.mutations(widget).subscribe(...)
). It is also RxJS compatible via their from
method:
rxjs.from(button.onSelect)
.pipe(debounceTime(100))
.subscribe(ev => ...);
Declarative UI
"Set" renamed to "Setter" to avoid confusion
Set
was introduced in 3.6 as a helper function for use with composite.apply
. When imported it shadowed the Set
class built in to JavaScript. While this was considered acceptable at the time, it caused more issue than inticipated, so it was renamed to Setter
. For backwards compatibility the function is also still exported as Set
as an alias, but only documented as Setter
.
"apply" is now declarative, supports new syntax
The "apply" method of Composite
can now be invoked in a declarative way using either the attribute apply
or the new JSX element <Apply>
. It can also, in addition to the established syntax, be given an array of Setter
elements (or a single one) for shorter syntax with better tooling support. This is a very convinient way to remove repetition in your UI code akin to CSS in HTML.
This example uses the apply
attribute to create 3 TextView
widgets that share a set of properties:
contentView.append(
Composite({
padding: 8,
apply: Setter(TextView, {
top: 'prev() 10',
background: '#66E',
textColor: 'white',
font: '24px'
}),
children: [
TextView({text: 'Hello'}),
TextView({text: 'Blue'}),
TextView({text: 'World'})
]
})
);
The apply
method/attribute/element can now also react to any property change of the widget it is called on. This can be used to write concise custom or functional components that update their content due to a change in any of their properties.
JSX element "Setter"
The Setter
function can also be used as a JSX element to set any attribute its parent. This includes listeners and callbacks, so for example the CollectionView
JSX element could now contain it's own cell factory:
<CollectionView stretch itemCount={people.length} cellHeight={256} updateCell={updateCell}>
<Setter target={CollectionView} attribute='createCell'>{() =>
<Composite onTap={handleTap}>
<ImageView top={16} centerX={0} width={200} height={200}/>
<TextView left={30} top='prev() 16' right={30} alignment='centerX'/>
</Composite>}
</Setter>
</CollectionView>
In general it's useful in any scenario where an attribute value would otherwise be too long for inlining.
Decorators
One-Way data binding via "@Bindall"
The "@Bindall" decorator can now be used to create one-way data bindings (in any direction) between a model and a child of a custom component, or the custom component itself. This is an alternative to the JSX based on-way data binding that may be more consistent when using the MVVM pattern.
Property based Dependency Injection
The "@Inject" decorator can now also be applied to properties, not just constructor parameters. This can be helpful to resolve circular dependency issues and result in an overall less cluttered constructor.