# Component properties

Every UI component exposes a set of properties that influence its behavior and layout. These properties are managed in the visual property editor and often do not require any code. In case a more dynamic behavior is required, you can use JavaScript to achieve that. This section introduces you to the key concepts and enables you to create highly dynamic, reactive component configurations.

### Property types

Every component property has a specific type, which determines what kind of values are permitted for that property, and which UI element is offered in the properties panel to modify it. Examples for such property types are:

* The `Disabled` property of a button is `boolean`, and hence is supposed to be either `true` or `false`. It is configurable via a switch element in the properties panel.
* The `On change run` property of a text-input is an `action`, and hence is supposed to contain an [action](https://docs.uify.io/writing-code/actions) that should be triggered when the particular event occurs. It is configurable via a select dropdown to choose any of the existing actions.
* The `Label` property of a text-input is a `stringWithJs`, which means that it can be any text with potentially [embedded JavaScript snippets](#embedding-javascript-in-text). It is configurable via a text-input field in the properties panel.
* The `Table data` property of a table is a `js` property. It is supposed to contain a JavaScript expression which evaluates to the final value of the property. It is configurable via a code-input field in the properties panel.

You can find a full list and description of all types in the [reference](#reference) below.

### Transforming properties to JavaScript

Many properties do not allow to apply dynamic configuration logic via JavaScript with their default input UI element. The best example for that is the `boolean` type, which uses a simple switch-input to set the property value. This input is only able to set that property statically to the value `true` or `false`. There are many scenarios where the property value should be calculated and updated dynamically though.

For such cases, some property types allow to switch from a static configuration (for example, using a switch) to a dynamic configuration (using JavaScript expressions). Such property transformation is indicated by a small `fx` icon around that property:

<div align="center"><img src="https://1582137130-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkTYtq8XZyg79paoHbd93%2Fuploads%2FUeSW9nXku251bagFU7We%2Fimage.png?alt=media&#x26;token=537f2085-6b71-4a0d-b91b-2c026e6a3501" alt="Transformation icons for boolean properties"></div>

Clicking on such an `fx` icon replaces the default UI element of the property with a code-input field. You can write any valid JavaScript expression into this input, and it will be evaluated dynamically to the final property value.

{% hint style="info" %}
The JavaScript engine expects that your dynamic expressions evaluate to the same data type that is expected by the particular property. For example, an expression in the code-input for a `boolean` property should evaluate to a `boolean` value. Otherwise, the preview will show you a type error (see the [preview section](#evaluation-preview) below)
{% endhint %}

A valid example of transforming a `boolean` property to a dynamic expression may look like this:

<div align="center"><img src="https://1582137130-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkTYtq8XZyg79paoHbd93%2Fuploads%2F4vXpdAdm56dQHSkP4rbe%2FScreen%20Cast%202022-07-21%20at%202.35.32%20PM.gif?alt=media&#x26;token=7e08def3-f543-44cd-9c63-57087e9b4fb3" alt="Using a JavaScript expression to set the boolean Required property"></div>

You can always switch back to a static property input in case a dynamic JavaScript expression is not required any more. The property will then keep the most recent value that your dynamic expression evaluated to.

Please check out the [property reference](#reference) to find out which property types can be transformed to JavaScript expressions, and which data types they expect.

### JavaScript properties

Certain properties require a JavaScript object or array by default, or are expected to always require dynamic calculation. Examples of such properties are the `Table Data` property of the Table component, or the `Data` property of the Funnel component. There is no way to, and no real meaning in, defining such properties statically, so their values are managed with a code-input field by default. These code-input fields visually look similar to regular text inputs, but allow you to write JavaScript expressions with all major IntelliSense features out of the box.

Below you see an example of such a JavaScript property with a minimalistic set of table data. You can immediately spot the syntax highlighting, which indicates a code-input field:

<figure><img src="https://1582137130-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkTYtq8XZyg79paoHbd93%2Fuploads%2FLIVlEXPjLyXWBUOCeImi%2FScreenshot%202023-05-03%20at%2018.20.30.png?alt=media&#x26;token=155def12-9d33-4be3-bbb4-ac08cd35c76a" alt=""><figcaption></figcaption></figure>

Code-input fields and regular text-input fields in the properties panel are usually easily distinguishable. Handling strings however sometimes leads to confusion, because they need to be entered differently. In a regular text-input, you can just enter the desired text without any special syntax. For a code-input field, this will however lead to an error:

<figure><img src="https://1582137130-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkTYtq8XZyg79paoHbd93%2Fuploads%2FtvgXUJcjpS8sY9yaJXlP%2Fimage.png?alt=media&#x26;token=0ccfe55d-9fa8-4e46-a289-d55b3d6ed8ed" alt=""><figcaption></figcaption></figure>

Since we are operating in a code-input field, all entered text is treated as a JavaScript expression. In this example, the text `Hello` is interpreted as a variable, which is not defined here.

The correct way to enter a string into such input is to enter those as valid JavaScript strings:

```typescript
// Single quotes work
'Hello'

// Double quotes too
"Hello"

// And template strings as well
`Hello`
```

### Embedding JavaScript in text

Properties that expect regular text for their values are modified via simple text-input fields. This avoids the necessity to write them as JavaScript strings every time (see previous section). However, these texts should contain dynamic content as well in many situations. For that reason, we allow to embed JavaScript expressions in such text fields using a [mustache](https://mustache.github.io/)-like syntax. You can enter regular text, but embed expressions by wrapping them in doubly-curly braces as follows:

<figure><img src="https://1582137130-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkTYtq8XZyg79paoHbd93%2Fuploads%2FZ7Yc43O4Ht3HScZsnCOQ%2Fimage.png?alt=media&#x26;token=7c1bb596-3a76-4647-80b0-b87a08472142" alt=""><figcaption></figcaption></figure>

You can embed as many expressions as you want, and they will all be replaced with the evaluated value at runtime.

{% hint style="info" %}
The runtime expects that these embedded expressions evaluate to a value of type string. In case a value with a different type is met, it performs its best effort to convert it to something textual, but a warning will be shown to you:

<img src="https://1582137130-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkTYtq8XZyg79paoHbd93%2Fuploads%2FbGu7X5MGxVwDyNezh73B%2Fimage%20(4).png?alt=media&#x26;token=c028e424-9494-4c45-b6f0-874a45637847" alt="" data-size="original">\
\
This value will be rendered correctly as "1 + 1 equals: 2", but it is still recommended that you take care of the conversion to string explicitly, to not rely on our implicit conversion mechanism.
{% endhint %}

### Evaluation preview

We have learned so far about two ways to dynamically calculate property values:

* [JS-properties](#pure-javascript-properties), that expect a JavaScript expression
* [Text-properties](#embedding-javascript-in-text), that allow to embed expressions with a mustache-like syntax

In both cases, you certainly would like to understand whether your code works exactly as you expect, and see what it evaluates to in result. As soon as your input contains some code, the application will render a small preview of what your input will evaluate to. In case there is no code in your text-input yet, such preview is unnecessary and will not be shown:

<figure><img src="https://1582137130-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkTYtq8XZyg79paoHbd93%2Fuploads%2FEzFSWgzJBLzLVhxwIk2V%2FScreen%20Cast%202022-07-22%20at%202.34.20%20PM.gif?alt=media&#x26;token=4b975aa4-297e-4d11-bc45-bd59ea65e501" alt=""><figcaption></figcaption></figure>

Syntax errors, and any errors during evaluation of your expressions, will be shown to you as well, to support you in fixing such errors quickly:

<figure><img src="https://1582137130-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkTYtq8XZyg79paoHbd93%2Fuploads%2FL63HcBsIaUsWmBCenTsL%2Fimage.png?alt=media&#x26;token=e0c747c7-3432-46b4-ade2-8bbfdc7a4b59" alt=""><figcaption></figcaption></figure>

On top of highlighting syntax and runtime errors, our engine checks for compatibility of the evaluated value of your expressions with the expected data type of the property that you are editing. For example, if you convert the switch of a `Disabled` property to a dynamic JavaScript expression, this expression should evaluate to a `boolean` value. If that is not the case, you will see an error hinting you to that fact:

<figure><img src="https://1582137130-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkTYtq8XZyg79paoHbd93%2Fuploads%2FJe6psrv02PmQTfBw56ZZ%2Fimage.png?alt=media&#x26;token=22056088-6176-48ce-8a5d-4b338005eac2" alt=""><figcaption></figcaption></figure>

Similar to the recommendation that [embedded expressions in text-inputs](#embedding-javascript-in-text) should evaluate to a string value, we recommend to follow these type recommendations precisely, and apply explicit conversions where necessary.

### Reactivity

The JavaScript runtime exposes specific variables in every code snippet that you write in the component properties. These variables expose evaluated properties of the UI components, actions, state variables and meta-data like the authenticated user ([read more](https://docs.uify.io/writing-code/exposed-variables)). These exposed properties are usually called "component API", "action API" and "state API" respectively.

For example, every UI component is exposed by its name as a separate variable. If you have a text-input component called `productName` in your app, this will be exposed as a global variable called `productName` in any code snippet as well. By using the `value` property of that object, you can access the current text in that input, and use it in your calculations:

![Displaying the value of the input field in a text-component](https://1582137130-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkTYtq8XZyg79paoHbd93%2Fuploads%2FxpBLzs6RIAowFFEfWchG%2FScreen%20Cast%202022-07-22%20at%202.54.07%20PM.gif?alt=media\&token=a714fb06-fe5e-4cb9-a85b-4dce10305d25)

Especially when dealing with component properties that change frequently (like the `value` of an input), the expressions using these properties should ideally update automatically whenever such change occurs. Using stale data in these expressions is clearly not desired.

For that reason, any property of any variable that you are using in JavaScript expressions behaves like an Observable. Whenever even a single used variable changes, the entire expression will be re-evaluated by the runtime. This might in turn trigger cascaded updates of other properties, until the affected part of the dependency graph is processed:

![Cascaded re-evaluation of several properties on input value change](https://1582137130-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkTYtq8XZyg79paoHbd93%2Fuploads%2FvLaF6YSR1ggx07fWgQso%2FScreen%20Cast%202022-07-22%20at%203.12.05%20PM.gif?alt=media\&token=1455983f-c0d4-45df-bb9c-adef7245fae7)

Let's unfold this example step by step:

1. `productName` is a regular text-input. Its value should be mirrored in the other two input fields.
2. `nameCopy1` receives the dynamic expression `{{productName.value}}`. This registers a dependency between its value and the `value` property of `productName`
3. `nameCopy2` receives the slightly different expression `{{nameCopy1.value}}`. This registers a dependency between its value and the `value` property of `nameCopy1`

Whenever the value of the input-field `productName` changes - regardless whether this change happens programmatically or via UI interaction of the user - the runtime follows a specific chain of logic. Let us assume for now that the `value` of the `productName` field has been changed to "Macbook":

1. All properties depending on `productName.value` are looked up from the internally managed dependency graph. This resolved to the `value` property of `nameCopy1`.
2. The property configuration of that `value` property, i.e. `{{productName.value}}`, is re-evaluated by the runtime, and evaluates to "Macbook".
3. Due to this new change of the `value` property of `nameCopy1`, the runtime performs another lookup for any property that depends on `nameCopy1.value` in the dependency graph. This recursive lookup resolved to the `value` property of `nameCopy2`.
4. The property configuration of that `value` property is `nameCopy1.value`, which will be re-evaluated as well. This evaluation leads to "Macbook" as well.
5. The updated calculated values for the `value` prop of `productName`, `nameCopy1` and `nameCopy2` are dispatched to the application state and rendered by each affected component.

The same mechanism is applied every time an exposed property of a component, action or state variable is changed. You can therefore rely on your JavaScript expressions always being evaluated to the latest value.

{% hint style="warning" %}
There are only two possible triggers for a dynamic property configuration to be re-evaluated:

1. The configuration, i.e. the code, is changed in the properties panel or by another collaborator
2. An exposed property, that is used in the code, has changed

Expressions like `{{new Date()}}` or `{{Math.random()}}` do not have any automated re-evaluation logic and might not behave as you expect.
{% endhint %}

The automatic tracking and re-evaluation of dependencies is a powerful feature, however it has a threat when used incorrectly: **dependency cycles**. Let's imagine the most basic example of such a cycle:

* The `value` prop of text-input component `A` contains: `{{B.value}}`
* The `value` prop of text-input component `B` contains: `{{A.value}}`

If either of the two values changes, we are entering an infinite update cycle. The runtime is able to detect such cycles and display a warning in such cases:

![Dependency cycles are detected](https://1582137130-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkTYtq8XZyg79paoHbd93%2Fuploads%2FOPPhMG9klmALFBNHwlA5%2FScreen%20Cast%202022-07-22%20at%203.38.46%20PM.gif?alt=media\&token=9c13e12a-9b22-4bf8-a354-02efdb181f62)

The outcome for the affected expressions / properties is not deterministic. It is highly recommended to immediately resolve any dependency cycle that occurs.

### Expanded code editor

Using JavaScript expressions in component properties is a powerful tool for creating dynamic and reactive UI behavior. In case your use case requires larger pieces of code, the input fields in the properties panel may be inconvenient though due to their small size. In this case, you have the ability to expand the input to a extended code editor with a large preview area. Use the expand-icon in the code input field to open the expanded code editor:

<figure><img src="https://1582137130-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkTYtq8XZyg79paoHbd93%2Fuploads%2FDnhpqsVVPyPRYI0PfP1Z%2FScreen%20Cast%202023-03-03%20at%2011.51.33%20AM.gif?alt=media&#x26;token=3ec4139b-f6fc-4219-beb2-a71bc1a1d0b7" alt=""><figcaption></figcaption></figure>

The expanded editor allows you to:

* Write larger expressions comfortably
* Inspect complex previews

### Reference

The following table lists all component property types and their main characteristics:

<table><thead><tr><th width="154.9442896935933">Property type</th><th width="212">Standard UI input</th><th data-type="checkbox">Transformable to JS</th><th width="150" data-type="checkbox">Embedded JS</th><th>Example property</th></tr></thead><tbody><tr><td>js</td><td>code input</td><td>false</td><td>false</td><td><code>Data</code> of a Table</td></tr><tr><td>stringWithJs</td><td>text input</td><td>false</td><td>true</td><td><code>Label</code> of a TextInput</td></tr><tr><td>boolean</td><td>switch</td><td>true</td><td>false</td><td><code>Disabled</code> of a Button</td></tr><tr><td>string</td><td>case by case</td><td>true</td><td>false</td><td><code>Label alignment</code> of a TextInput</td></tr><tr><td>array</td><td>code input</td><td>false</td><td>false</td><td><code>Options</code> of a Select</td></tr><tr><td>color</td><td>text input / color picker</td><td>true</td><td>false</td><td><code>Value color</code> in a TextInput</td></tr><tr><td>action</td><td>Dropdown select</td><td>false</td><td>false</td><td><code>On click run</code> action of Button</td></tr></tbody></table>
