Skip to content

Commit

Permalink
folder structure
Browse files Browse the repository at this point in the history
  • Loading branch information
namnguyen20999 committed Dec 6, 2024
1 parent 607dbd2 commit ee9695d
Show file tree
Hide file tree
Showing 10 changed files with 180 additions and 236 deletions.
2 changes: 1 addition & 1 deletion docs/userman/gui/extension/dynamic_element/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -355,5 +355,5 @@ Here are the sections that address the different use cases that your custom
element may need:

- [Scalar properties](scalar_props.md)
- [Tabular data properties](tabular_data_props.md)
- [Tabular data properties](../extension_tabular_data)

211 changes: 0 additions & 211 deletions docs/userman/gui/extension/extension_data.md

This file was deleted.

155 changes: 155 additions & 0 deletions docs/userman/gui/extension/extension_list_of_values.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
In the previous section, we discussed creating dynamic elements. In Taipy GUI, lists can be bound to Python variables or
expressions, allowing real-time updates in the UI. Custom elements that handle lists should define their properties using
the `PropertyType^` class to specify the format of list values. This setup supports multidimensional data binding, ensuring
that any changes to the list automatically refresh the display.

# Using list of values

In this section, we'll design a visual component that represents a list of programming languages. Each language will be
displayed with its name and an icon.

This component will take a property containing a list of values and render them as a list.
When a Python variable is bound to this property, any updates to the variable will instantly reflect in the displayed list,
enabling real-time synchronization.

## Declaring the element {data-source="gui:doc/extension/example_library/example_library.py#L52"}

Starting from the code mentioned above, here is how you would declare this new element:
```python title="example_library.py"
from taipy.gui.extension import Element, ElementLibrary, ElementProperty, PropertyType

class ExampleLibrary(ElementLibrary):
def __init__(self) -> None:
# Initialize the set of visual elements for this extension library
self.elements = {
"visual_label_list": Element(
"lov",
{
"lov": ElementProperty(PropertyType.lov),
"sort": ElementProperty(PropertyType.string),
},
# The name of the React component (VisualLabelList) that implements this custom
# element, exported as LabeledItemList in front-end/src/index.ts
react_component="VisualLabelList",
)
}
```
The detailed explanation of the code is as follows:

- The *visual_label_list* element includes two properties: *lov* and *sort*.
- The *lov* property has the type `PropertyType.lov^`, meaning it holds a list of values and is dynamic.
- The *sort* property has the type `PropertyType.string^`, meaning it holds a string value. Because this property is
static, it is not updated automatically should the bound variable be changed.
- *get_name()* and *get_elements()* remain the same as in the previous stages of building the extension library example.

## Creating the React component {data-source="gui:doc/extension/example_library/front-end/src/VisualLabelList.tsx"}

The React component for the *visual_label_list* element is defined as follows:
```tsx title="VisualLabelList.tsx"
import React, { useMemo } from "react";
import { LoV, useLovListMemo } from "taipy-gui";

interface VisualLabelListProps {
lov?: LoV;
defaultLov?: string;
sort?: "asc" | "desc";
}

const styles = {
listItem: {
display: "flex",
alignItems: "center",
},
image: {
marginRight: "8px",
width: "1em",
height: "1em",
},
};

const VisualLabelList: React.FC<VisualLabelListProps> = ({ lov, defaultLov = "", sort }) => {
const lovList = useLovListMemo(lov, defaultLov);

const sortedLovList = useMemo(() => {
if (sort) {
return lovList.slice().sort((a, b) => {
return sort === "asc" ? a.id.localeCompare(b.id) : b.id.localeCompare(a.id);
});
}
return lovList;
}, [lovList, sort]);

return (
<div>
<ul>
{sortedLovList.map((item, index) => (
<li key={index} style={styles.listItem}>
{typeof item.item === "string" ? null : (
<img src={item.item.path} alt={item.item.text} style={styles.image} />
)}
{item.id}
</li>
))}
</ul>
</div>
);
};

export default VisualLabelList;
```

The detailed explanation of the code is as follows:

- The *lov* property, defined as `PropertyType.lov^`, expects a value of type
[`LoV`](../../../refmans/reference_guiext/type-aliases/LoV.md).
- Using Taipy GUI’s [`useLovListMemo()`](../../../refmans/reference_guiext/functions/useLovListMemo.md) hook, we
create a memoized list of values based on this *lov* property, efficiently managing the component’s list of values.
- To enhance this list, we can apply sorting using the *sort* property, which accepts either “asc” for ascending or
“desc” for descending order. Since *sort* is static, a default value is unnecessary. When set to "asc" or "desc," the
list is sorted accordingly. If *sort* is not defined in the script, the list displays values in their original order.

## Exporting the React component {data-source="gui:doc/extension/example_library/front-end/src/index.ts"}

When the component is entirely defined, it must be exported by the library's JavaScript bundle.
This is done by adding the export directive in the file *<project dir>/<package dir>front-end/src/index.ts*.

```ts title="index.ts"
import VisualLabelList from "./VisualLabelList";

export { VisualLabelList };
```

## Using the element {data-source="gui:doc/extension/visual_label_list.py"}

To use the *visual_label_list* element in a Python script, you can follow the example below:
```python title="List of items"
languages = [
["Python", Icon("images/python.png", "Python logo")],
["JavaScript", Icon("images/javascript.png", "JavaScript logo")],
["TypeScript", Icon("images/typescript.png", "TypeScript logo")],
["Java", Icon("images/java.png", "Java logo")],
["C++", Icon("images/cpp.png", "C++ logo")],
]

page = """
<|{languages}|example.visual_label_list|sort=asc|>
"""
```

In this example, the *languages* list contains a [`list of value`](../binding.md#list-of-values),
each with a name and an icon. The *page* variable contains a string that uses the *visual_label_list* element to display
the list of languages in ascending order. The *sort* property is set to “asc” to sort the list alphabetically by
language name. When the page is rendered, the list will display the languages in the specified order.

By following these steps, you can create the element that displays a list of values and updates in real time as
the underlying data changes. This approach allows you to build custom elements that can manage and display collections
of data, providing a more interactive and responsive user interface.

When you run this application, the page displays the element like this:

<figure>
<img src="../visual_label_list-d.png" class="visible-dark"/>
<img src="../visual_label_list-l.png" class="visible-light"/>
<figcaption>Visual labeled list</figcaption>
</figure>

Loading

0 comments on commit ee9695d

Please sign in to comment.