# API (/xml/ui_elements/api)



The `<api>` tag can be a child of `<widget>` and `<component>` tags.
(`<screen>`s don't support custom APIs.)

The only common point is that both Widgets and Components support having
`<prop>` (properties) in the `<api>` tag to describe their interface.

However, as Widgets and Components work very differently (Widgets have C code,
but Components are pure XML), even properties are interpreted differently.

Components [#components]

Overview [#overview]

While Widgets can have complex `set`/`get` APIs, Components are very simple.

When a component's XML is converted to C files, only a `create` function is generated,
where all the `<prop>`\s are arguments. For example:

```xml title="xml" lineNumbers=1
<api>
    <prop name="prop1" type="int"/>
    <prop name="prop2" type="string"/>
</api>
```

Referencing properties [#referencing-properties]

`<prop>`s are simply forwarded to Widget or Component APIs.
For example, if a component has `<prop name="button_label" type="string"/>`,
it can be used in a label child as `<lv_label text="$button_label"/>`.

In the code generated by LVGL's UI Editor, these are passed as arguments in create/set functions.

Default values [#default-values]

Since each property is passed as an argument to the create function, each must have a value.
This can be ensured by:

* Simply setting them in the XML instance
* Providing a default value in the `<api>`, e.g., `<prop name="title" type="string" default="my_default_text"/>`

Code generation [#code-generation]

LVGL's UI Editor can also generate code from the component's XML. Depending on the `<api>`, a function like
this is generated:

```c title=" " lineNumbers=1
lv_obj_t * my_component_create(lv_obj_t * parent, int32_t prop1, const char * prop2);
```

These properties are set once (at creation time), and there are no specific
`set` functions to modify the property later. LVGL's general API can still be
used to modify any widget in the component, but no dedicated API functions are generated.

Slots [#slots]

With the help of a "slot" any UI element in the component can be easily exposed as a parent
that can be referenced later and children can be created there.

Just add `<slot name="my_slot"/>` to the `<api>` to tell the Editor
which children to expose.

To target a slot on an instance of a component create a child like
`<component_name-slot_name>` and add the children as needed.

Slots are available only for components. In case of a widget the more powerful
[elements with get access type](/xml/ui_elements/api) can be used.

Slots are very useful to create components like screen templates where the user is
allowed to create children on certain internal UI elements.

```xml title="xml" lineNumbers=1
<!-- simple_screen.xml -->
<component>
    <api>
        <slot name="icon_area"/>
        <slot name="content_area"/>
    </api>

    <view width="100%" height="100%" flex_flow="column">
        <lv_obj name="icon_area" width="100%" height="30" flex_flow="row"/>
        <lv_obj name="content_area" width="100%" flex_grow="1" flex_flow="column"/>
    </view>
</component>

<!-- main_screen.xml -->
<component>
    <view extends="simple_screen" width="100%">
        <simple_screen-icon_area>
            <lv_image src="img1"/>
            <lv_image src="img2"/>
        </simple_screen-icon_area>

        <simple_screen-content_area>
            <lv_label text="Some content"/>
        </simple_screen-content_area>
    </view>
</component>
```

Limitations [#limitations]

Note that none of the Widget API features such as `<param>`, `<enumdef>`, or `<element>`
can be used for Components. Only simple properties that are forwarded are supported.

Example [#example]

```xml title="xml" lineNumbers=1
<!-- my_button.xml -->
<component>
    <api>
        <prop name="button_icon" type="image" default="NULL"/>
        <prop name="button_label" type="string" default="Label"/>
    </api>

    <view extends="lv_button" flex_flow="row" width="100%">
        <lv_image src="$button_icon" inner_align="stretch" width="16" height="16"/>
        <lv_label text="$button_label"/>
    </view>
</component>

<!-- my_list.xml -->
<component>
    <api>
        <slot name="header"/>
    </api>

    <view flex_flow="column">
        <lv_obj name="header" width="100%"/>
        <my_button button_label="First"/>
        <my_button button_label="Wifi" button_icon="img_wifi"/>
        <my_button button_label="Third"/>
    </view>
</component>
```

Widgets [#widgets]

Properties [#properties]

Properties are the core part of describing a Widget's API.

```xml title="xml" lineNumbers=1
<api>
    <prop name="text" type="string" help="Text of the label."/>
</api>
```

Parameters [#parameters]

Some properties take multiple parameters. For example:

<ApiLink name="lv_label_set_bind_text" display="lv_label_set_bind_text(label, subject, &#x22;%d °C&#x22;)" />

It's described as:

```xml title="xml" lineNumbers=1
<api>
    <prop name="bind_text" help="Bind a subject's value to a label.">
        <param name="bind_text" type="subject" help="Integer or string subject"/>
        <param name="fmt" type="string" help="Format string, e.g. %d °C "/>
    </prop>
</api>
```

And used as:

```xml title="xml" lineNumbers=1
<lv_label bind_text="subject" bind_text-fmt="%d °C"/>
```

Parameters with the same name as the property can be referenced directly.
Other parameters use `property-param` notation.

Unset parameters fall back to:

* Their default value (if defined)
* Type-specific defaults (e.g., 0, false, NULL)

Mapping [#mapping]

Each `<prop>[is mapped to a `set`function. This mapping is implemented
in the Widget's XML parser.
See`the LVGL XML parsers]\([https://github.com/lvgl/lvgl/tree/master/src/others/xml/parsers](https://github.com/lvgl/lvgl/tree/master/src/others/xml/parsers)).

If `<param>`s are used, they are passed to the same `set` function.
If a property is not set on a Widget instance, it is skipped and the Widget's
built-in default is used.

\<enumdef> [#enumdef]

Only used with Widgets, this tag defines enums for parameter values.

```xml title="xml" lineNumbers=1
<api>
    <enumdef name="my_widget_mode" help="Possible modes">
        <enum name="normal" help="Normal mode" value="0x10"/>
        <enum name="inverted" help="Inverted mode"/>
    </enumdef>
    <prop name="mode" help="Set Widget mode">
        <param name="mode" type="enum:my_widget_mode"/>
    </prop>
</api>
```

The actual values of the enum fields are not important during code export as only the names are used and resolved by the compiler.
XML parsers must handle mapping enum string names (e.g. `"normal"`) to C enums (e.g. `MY_WIDGET_MODE_NORMAL`).

`<element>` [#element]

Also exclusive to Widgets, elements define sub-widgets or internal structures
(e.g., chart series, dropdown lists, tab views).

Elements are also very useful to create "slots" (similar to tabview tabs), like a content and header area for a window widget, where
children can be created directly.

Elements are described inside the `<api>` tag, and they can have `<arg>` and `<prop>` children:

* `<arg>`\s are required and used when creating/getting the element.
* `<prop>`\s are optional and mapped to setters.

Here's an example to define an "indicator" that can be added dynamically to a widget. It will create `my_indicator_t *`
elements, the same way as, for example, <ApiLink name="lv_chart_add_series" /> works.

```xml title="xml" lineNumbers=1
<api>
    <element name="indicator" type="my_indicator_t" help="The indicator of my_widget" access="add">
        <!-- args are passed when the element is created -->
        <arg name="color" type="color"/>
        <arg name="max_value" type="int"/>

        <!-- props can be set by setters at any time -->
        <prop name="value" type="int"/>
    </element>
</api>
```

Element `access` types can be:

* `add`: Create multiple elements dynamically. For example, tabview tabs.
* `get`: Access implicitly created elements. For example, dropdown lists.
* `set`: Access indexed parts. For example, table cells.
* `custom`: Map custom C functions to XML, e.g. `bind_state_is_eq`

As `add` and `get` elements return an object, they also have a type.
This type can be any custom type, for example, `type="my_data"`. In the exported code, the
return value will be saved in a `my_data_t *` variable.

If the type is `type="lv_obj"`, it allows the element to have child widgets or components.

Elements are referenced as `<widget-element>` in the `<view>`.
The parts of the name are separated by `-`. As `-` is not allowed inside names, it's safe to use
as a separator.

Note that only the API can be defined in XML for elements; implementations must be in C.

access="add" [#accessadd]

Elements are created via an `add` function:

```xml title="xml" lineNumbers=1
<api>
    <element name="indicator" type="obj" help="The indicator of my_widget" access="add">
        <arg name="color" type="color"/>
        <arg name="max_value" type="int"/>
        <prop name="value">
            <param name="value" type="int"/>
        </prop>
    </element>
</api>
```

Used in a view:

```xml title="xml" lineNumbers=1
<my_widget width="100px">
    <my_widget-indicator name="indic1" color="0xff0000" max_value="120" value="30"/>
</my_widget>
```

LVGL's UI Editor generates this:

```c title=" " lineNumbers=1
lv_obj_t * my_widget_add_indicator(lv_obj_t * parent, lv_color_t color, int32_t max_value);
void my_widget_set_indicator_value(lv_obj_t * obj, int32_t value);
```

access="get" [#accessget]

Used for internal/implicit elements:

```xml title="xml" lineNumbers=1
<api>
    <element name="control_button" type="obj" help="A control button of my_widget" access="get">
        <arg name="index" type="int"/>
        <prop name="title" type="string"/>
    </element>
</api>
```

Used in a view:

```xml title="xml" lineNumbers=1
<my_widget width="100px">
    <my_widget-control_button name="btn1" index="3" title="Hello"/>
</my_widget>
```

LVGL's UI Editor generates this:

```c title=" " lineNumbers=1
lv_obj_t * my_widget_get_control_button(lv_obj_t * parent, int32_t index);
void my_widget_set_control_button_title(lv_obj_t * obj, const char * text);
```

access="set" [#accessset]

Used for indexed access, like setting values in a table:

```xml title="xml" lineNumbers=1
<api>
    <element name="item" type="obj" access="set">
        <arg name="index" type="int"/>
        <prop name="icon" type="img_src"/>
        <prop name="color" type="color"/>
    </element>
</api>
```

Used in a view:

```xml title="xml" lineNumbers=1
<my_widget width="100px">
    <my_widget-item index="3" icon_src="image1" color="0xff0000"/>
</my_widget>
```

LVGL's UI Editor generates this:

```c title=" " lineNumbers=1
void my_widget_set_item_icon(lv_obj_t * parent, int32_t index, const void * icon_src);
void my_widget_set_item_color(lv_obj_t * parent, int32_t index, lv_color_t color);
```

access="custom" [#accesscustom]

Used to describe any custom API functions with a custom name.
"custom" elements can have only arguments and no `type`, so they are pure setters.

```xml title="xml" lineNumbers=1
<element name="bind_color" access="custom">
    <arg name="subject" type="subject"/>
    <arg name="new_color" type="color"/>
    <arg name="ref_value" type="int"/>
</element>
```

Used in a view:

```xml title="xml" lineNumbers=1
<my_widget width="100px">
    <my_widget-bind_color subject="subject_1" color="0xff0000" ref_value="15"/>
</my_widget>
```

LVGL's UI Editor generates this:

```c title=" " lineNumbers=1
void my_widget_bind_color(lv_obj_t * parent, lv_subject_t * subject, lv_color_t color, int32_t ref_value);
```
