` container, there are times and situations where the `Label` component can cause placement/alignment issues or even configuration issues if the parent element is not compatible with having a `
` container as a child.
In contrast, the `Content` component renders the value given by the `text` property _without_ any additional container.
For example:
```yaml
- component: f7-row
config:
class: fancy-row
slots:
default:
- component: Content
config:
text: Content text here
```
renders in the page HTML as:
```html
Content text here
```
With no container, there is no possibility to add `class` or `style` configuration to the `Content` component.
### HTML components
The custom widget system can also be used to build HTML more directly.
The `component` property can also be set to any recognized HTML tag.
When used in this manner, the component accepts any configuration paramaters that can be passed to the tag as HTML attributes (inlcuding, of course, `class` and `style`).
There is an additional configuration parameter, `content` which allows for content text to be inlcuded in the tag.
HTML components also accept a `default` slot which will render a child component inside the tag.
#### HTML component examples
The widget YAML:
```yaml
- component: div
config:
content: Make this text bold
style:
font-weight: bold
```
Renders to the HTML:
```html
Make this text bold
```
To put more complex HTML hierarchies, use the component's `default` slot:
```yaml
- component: div
config:
style:
font-style: italic
slots:
default:
- component: Content
config:
text: "This text starts with italics "
- component: span
config:
content: but then becomes BOLD!
style:
font-weight: bold
```
Renders to the HTML:
```html
This text starts with italics but then becomes BOLD!
```
## The Expression Syntax
The widget expression system uses a JavaScript-like expression parser, [jse-eval](https://github.com/6utt3rfly/jse-eval).
In order to remain light-weight and responsive, this is not a complete JavaScript library, but nearly all of the basic function is provided along with some more advanced features.
### Advanced expression features
#### Arrow functions
Many standard JavaScript methods take a function as a parameter.
The expression parser can parse arrow functions as the paramters of these methods.
Here an arrow function is used in conjunction with the `.find()` method to locate the item object in an array of items (such as is returned by a `oh-repeater`) with a particular name.
The label of the found item is then used as the title of a component.
```yaml
title: =someItemList.find( (x) => x.name=="KitchenSwitch" ).label
```
#### String templates
String templates are a much more human-readable way of creating strings with incorporated dynamic values.
String templates are surrounded by backticks (
\`string template\`
) instead of single- or double-quotes.
Inside string templates, variable values can be inserted with `${variable}` syntax.
Here the value of the widget property `props.page` is included in the text of a component by a string template.
```yaml
text: =`This button opens the ${props.page} page`
```
#### Regular expressions
Regular expressions (regex) allow for complex search or replace string operations.
Many of the JavaScript string methods accept regex parameters expressed as the regex string between two forward slashes (`/regex here/`).
Here a widget property containing an Item name is searched using regex and the first capture (in this case all characters between two underscores) is returned as a component label.
```yaml
label: =props.item.match(/_(.*)_/)[1]
```
#### Objects
The variable action allows components in widgets to pass information back and forth when there is user interaction.
Often this informtation is simple, such as a single string or input value.
Sometimes, however, it is helpul to add more information to a variable and for these instances JavaScript opjects are useful.
The widget system can create objects in two different ways.
Objects can be defined within the expression system using the standard JavaScript syntax: `{'key1':'value1','key2':'value2'}`.
::: tip
Due to the special meaning of `:[space]` in yaml, it is best to have no spaces between the `:` and the value.
If you have `:[space]` anywhere in your expression it will raise a YAML error unless you enclose the entire expression (= included) in another layer of quotes.
:::
Here a variable is set to an object with `name` and `selected` keys using the object expression.
```yaml
actionVariable: myObject
actionVariableValue: ={'name':props.item,'selected':true}
```
The other way to create objects is to take advantage of the relationship between YAML and JSON and place the key:value pairs as YAML keys under the initial key.
Here is a variable definition with the same results as the one above using the YAML syntax.
```yaml
actionVariable: myObject
actionVariableValue:
name: =props.item
selected: =true
```
In both cases, the variable can now be referenced by other components as `vars.myObject` with keys `vars.myObject.name` and `vars.myObject.selected`.
The object expression can also be used to simulate a `switch` control statement.
The most common flow control statement in the expressions is the [conditional (ternary) operator](building-pages.html#dynamically-configuring-components-with-expressions) which is very efficient for selecting from two options based on a single boolean criterion.
If you have a list of possible options, you can string multiple ternary operators together, but this grows cumbersome very quickly.
For example, if there is an HVAC with a mode item that can be set to `heat`, `cool`, `auto`, and `off` modes, it requires 4 nested ternary operators to set a component's background color to match the current HVAC mode (with a fall back option if the item has some other state, e.g. `null`).
```yaml
background: =(@@hvacModeItem == 'heat')?'orange':(@@hvacModeItem == 'cool')?'blue':(@@hvacModeItem == 'auto')?'green':(@@hvacModeItem == 'off')?'white':'red'
```
To use an object instead, simply create an object with keys for each of the Item's expected states, and give each key the desired output value.
Referencing that object using the Item's state will return the desired value and following that with a simple `OR` statement will provide the fallback condition if the object reference is undefined.
```yaml
background: =({'heat':'orange','cool':'blue','auto':'green','off':'white'})[@@hvacModeItem] || 'red'
```