# Components (/syntax/components)



Components are powerful XML-based building blocks that let you create reusable, modular UI elements without writing C code.

Overview [#overview]

Components are one of the main building blocks for creating new UI elements. They are wrapped into a `<component>` root element and can have the following child XML tags:

* [`animations`](./animations) - Define timeline based animations
* [`consts`](./constants) - Local constants
* [`api`](./api) - Custom properties and slots (without `<enumdef>`s)
* [`styles`](./styles) - Local styles
* [`view`](./view) - Component structure
* [`previews`](./preview) - Preview configurations

Although components cannot contain C code, they are very powerful:

* They can extend another Component or Widget (that is the base can be defined)
* Components can be built from Widgets and other Components
* A custom [API](./api) can be defined
* Local [styles](./styles) can be defined, and global styles can be used
* Local [constants](./constants) can be defined, and global constants can be used
* Function calls, subject (variable) changes, or screen load/create events can be added
* Previews can be defined to preview components in various settings in the UI Editor

Extending Components and Widgets [#extending-components-and-widgets]

When a Component is created, it can extend another Component or Widget like [`<view extends="lv_slider">`](./view). If a Widget is extended, the component can use the Widget's API, for example:

```xml title="xml" lineNumbers=1
<component>
  <view extends="lv_slider" min_value="20"/>
</component>
```

If a Component is extended, the `api` properties can be used:

```xml title="xml" lineNumbers=1
<view extends="my_button" button_text="Apply">
```

Runtime vs. Code Generation [#runtime-vs-code-generation]

Unlike Widgets (which are always compiled into the application), Components can either:

1. Be exported to C code by the Editor and compiled with the application, or
2. Be loaded at runtime from XML

Using Components in XML [#using-components-in-xml]

Basic XML Usage [#basic-xml-usage]

Using Components in XML is very intuitive. The name of the Component can be used as an XML tag in the [`view`](./view) of other Components, [Screens](./screens), and [Widgets](./widgets). Component properties are simply XML attributes.

```xml title="xml" lineNumbers=1
<!-- my_button.xml -->
<component>
  <view extends="lv_button" flex_flow="row">
    <lv_image src="logo"/>
    <my_h3 text="Hello world"/>
  </view>
</component>
```

Exporting Components to Code [#exporting-components-to-code]

If loading XML at runtime is not needed, the [Editor](../editor/overview) or the [CLI](../cli) can export C and H files from the XML files of the Components. The resulting code is completely self-sufficient and **the XML files are not needed anymore**. The resulting code is similar to what you could write manually.

The exported code looks like this:

```c title=" " lineNumbers=1
lv_obj_t * component_name_create(lv_obj_t * parent, ...api properties...);
```

where `component_name` is the name of the  Component's XML file name.

When a Component is used in another Component's XML code and the code is exported, this `create` function will be called. This means Components do not have a detailed set/get API but are created with a fixed set of parameters.

If you need to access or modify values dynamically, it is recommended to use [data bindings via Subject](./data-binding). You can also call these `..._create()` functions at any time from application code to create new Components on demand.

Defining Custom Properties [#defining-custom-properties]

The properties of child elements can be adjusted directly:

```xml title="xml" lineNumbers=1
<my_button x="10" width="200"/>
```

However, you can also define custom properties in the [`api` tag](./api). These properties can then be passed to any properties of the children by referencing them using `$`. For example:

```xml title="xml" lineNumbers=1
<!-- my_button.xml -->
<component>
  <api>
    <prop name="btn_text" type="string"/>
  </api>

  <view extends="lv_button">
    <lv_label text="$btn_text"/>
  </view>
</component>
```

And it can be used like:

```xml title="xml" lineNumbers=1
<!-- my_list.xml -->
<component>
  <view>
    <my_button btn_text="First"/>
    <my_button btn_text="Second"/>
    <my_button btn_text="Third"/>
  </view>
</component>
```

Optional properties [#optional-properties]

In this setup, the `btn_text` property is mandatory. However, you can make it optional by setting a default value:

```xml title="xml" lineNumbers=1
<prop name="btn_text" type="string" default="Title"/>
```

See the [API documentation](./api) for more details and XML syntax reference for all the supported types.

Complete Examples [#complete-examples]

The following examples demonstrate parameter passing, styles, and constants in Components.

Simple Component [#simple-component]

```xml title="xml" lineNumbers=1
<!-- h3.xml -->
<component>
  <view extends="lv_label" style_text_color="0xffff00"/>
</component>
```

Advanced Component with Styles and Constants [#advanced-component-with-styles-and-constants]

```xml title="xml" lineNumbers=1
<!-- red_button.xml -->
<component>
  <api>
    <prop type="string" name="btn_text" default="None"/>
  </api>

  <consts>
    <int name="thin" value="2"/>
  </consts>

  <styles>
    <style name="pressed_style" border_width="#thin" border_color="0xff0000"/>
  </styles>

  <view extends="lv_button" style_radius="0" style_bg_color="0xff0000">
    <style name="pressed_style" selector="pressed"/>
    <h3 text="Some text"/>
    <h3 text="$btn_text" y="40"/>
  </view>
</component>
```
