Styles binding

A significant goal in our UI design is to provide visual cues driven by the data. Alongside this, we incorporate dynamic animations, selectively hide or display elements, and conditionally disable components. Furthermore, from a binding engine perspective, we aim to facilitate common UI modifications such as adjusting color schemes, resizing elements, toggling visibility, and updating font styles.

When it comes to updating styles in a UI, there are two primary methods:

  1. Style Binding: This allows you to directly set style properties on an element. For example, changing the background color, adjusting the font size, or modifying the margin. It provides a dynamic way to alter individual CSS properties based on data or conditions.
  2. Class List Binding: This method lets you add or remove entire classes on the element. Instead of changing individual style properties, you can define a set of styles in a class and then conditionally apply or remove that class. It’s especially useful when you have predefined styles in classes and want to toggle between them based on certain conditions or actions.

Style binding

Our goal with style binding is to implement the subsequent JavaScript code.

element.style.background = 'red';

This is a basic illustration, but the intricacies can vary. You might merely wish to modify the style to reflect the context property. Perhaps you aim to change the style contingent on a specific condition, applying the style only if the criteria are fulfilled and removing it otherwise. Alternatively, you might want the style to have a value regardless of the condition. To cater to these needs, we offer standard binding, binding with an ‘if’ attribute, and styling through a case statement.

// bind the background style property to the property called background on the context
<div style.background="background">...</div>

// set the background style property based on a condition
<div style.color.if="background == 'red' ? '#9000ff' : '#ff0090'">...</div>

// set the background style property using a case statement
<div style.color.case="background == 'red': 'red', background == 'blue': 'blue', default: 'green'"></div>

Take note that the ‘if’ binding employs a syntax akin to a JavaScript ternary operator. The case statement functions similarly to a dictionary, where the key represents the expression, and the dictionary’s value corresponds to the style value. Distinct case statements are distinguished by commas.

Class list binding

In JavaScript, the classList property provides methods to conveniently manipulate the class list of an element. It allows you to add, remove, toggle, and check the presence of classes without having to deal with string manipulation.

Here’s a breakdown of some common classList methods:

  1. add(): Adds one or more classes to an element.
  2. remove(): Removes one or more classes from an element.
  3. toggle(): Toggles a class; if the class exists, it removes it and if it doesn’t, it adds it.
let divElement = document.getElementById("myDiv");

// Add a class
divElement.classList.add("new-class");

// Remove a class
divElement.classList.remove("example-class");

// Toggle a class
divElement.classList.toggle("toggle-class");

When manipulating styles, you’re typically adjusting one property at a time. However, with classes, you have the advantage of addressing multiple properties simultaneously. The syntax for class bindings bears resemblance to that of style bindings, but it now accommodates arrays of values. When dealing with multiple values, they should be enclosed within square brackets.

It’s crucial to understand that with class list binding, values are removed when the associated conditions aren’t met. For instance, if there’s a binding checking whether the “background” property in the context is set to “red”, it will add the “red” class to the element. However, if this condition isn’t satisfied, the “red” class gets eliminated. In a way, it’s like toggling between classes. This behavior extends to if-else constructs too. When a condition is true, the respective class is applied, but if it turns false, that class is taken away and the alternative is added. This applies to both if and case statements.

// add the "red" class if the condition passes
<div classlist.if="background == 'red' ? 'red'">

// if the expression passes add the red class else add the blue class
<div class="color" classlist.if="background == 'red' ? 'red' : 'blue'">

// if the condition passes add the classes, "white" and "green"
// if the condition fails add the classes "blue" and "Yellow"
<div classlist.if="background == 'red' ? ['white', 'green'] : ['blue', 'yellow']">

// standard case statement
<div classlist.case="background == 'red': 'red', background == 'blue': 'blue'">

// case statement with a default value if none of the expressions pass
<div classlist.case="background == 'red': 'red', background == 'blue': 'blue', default: 'green'">