diff --git a/docs/userman/gui/extension/chess_game-d.png b/docs/userman/gui/extension/chess_game-d.png new file mode 100644 index 000000000..9bffd9d0e Binary files /dev/null and b/docs/userman/gui/extension/chess_game-d.png differ diff --git a/docs/userman/gui/extension/chess_game-l.png b/docs/userman/gui/extension/chess_game-l.png new file mode 100644 index 000000000..cdf7ffb70 Binary files /dev/null and b/docs/userman/gui/extension/chess_game-l.png differ diff --git a/docs/userman/gui/extension/dynamic_element/chess_game-d.png b/docs/userman/gui/extension/dynamic_element/chess_game-d.png deleted file mode 100644 index 6a6d44173..000000000 Binary files a/docs/userman/gui/extension/dynamic_element/chess_game-d.png and /dev/null differ diff --git a/docs/userman/gui/extension/dynamic_element/chess_game-l.png b/docs/userman/gui/extension/dynamic_element/chess_game-l.png deleted file mode 100644 index 46d972390..000000000 Binary files a/docs/userman/gui/extension/dynamic_element/chess_game-l.png and /dev/null differ diff --git a/docs/userman/gui/extension/dynamic_element/index.md b/docs/userman/gui/extension/dynamic_element/index.md index 72ee1ad73..5893112a8 100644 --- a/docs/userman/gui/extension/dynamic_element/index.md +++ b/docs/userman/gui/extension/dynamic_element/index.md @@ -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) diff --git a/docs/userman/gui/extension/dynamic_element/list_of_value_props.md b/docs/userman/gui/extension/dynamic_element/list_of_value_props.md new file mode 100644 index 000000000..f26f747b5 --- /dev/null +++ b/docs/userman/gui/extension/dynamic_element/list_of_value_props.md @@ -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 dynamic 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 a dynamic element {data-source="gui:doc/extension/example_library/example_library.py#L45"} + +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" linenums="1" +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 = ({ 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 ( +
+ +
+ ); +}; + +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 */front-end/src/index.ts*. + +```js 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: +```py 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 a dynamic 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: + +
+ + +
Visual labeled list
+
+ diff --git a/docs/userman/gui/extension/extension_assets.md b/docs/userman/gui/extension/extension_assets.md index 7bf734cb4..0d3372ce9 100644 --- a/docs/userman/gui/extension/extension_assets.md +++ b/docs/userman/gui/extension/extension_assets.md @@ -1,21 +1,41 @@ # Accessing the library assets -Say we want to display a small image next to the text. That would be useful in the -situation where we apply our *caption* control to represent a company name along with -its logo. +In certain scenarios, you might want to enrich your user interface by displaying a small image alongside text. +For example, when using a caption control to represent a company name along with its logo, +adding an image can enhance visual context and usability. -In HTML, you would create an `img` tag, where the source URL is set to the path of the -image. However, in order to protect the application from attacks, Taipy provides the -method `ElementLibrary.get_resource()` that let the application filter what resources -are requested, and return the actual files according to the application setting. +Traditionally, in HTML, you would use an `img` tag with the src attribute pointing to the image’s file path. +However, directly referencing resources in this way can expose your application to potential security vulnerabilities, +such as unauthorized access or malicious resource requests. +To mitigate these risks, Taipy introduces the `ElementLibrary.get_resource()^` method. +This method acts as a secure gateway for resource handling, +allowing the application to validate and filter resource requests based on predefined settings. +It ensures that only authorized and properly configured files are served, protecting your application while maintaining +functionality. +## Declaring element {data-source="gui:doc/extension/example_library/example_library.py#L62"} -!!! warning "Work in Progress" - This section still requires significant work, which is in progress. - At this time, Taipy GUI provides a custom element library example - with lengthy explanations on how to build it.
- Please look into the `doc/extension` directory where Taipy GUI is - installed for more information.
- You can also look at this example directly on - [GitHub](https://github.com/Avaiga/taipy/tree/[BRANCH]/doc/gui/extension). +```python title="example_library.py" +import base64 + +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 + logo_path = self.get_resource("assets/logo.png") + with open(logo_path, "rb") as f: + logo_base64 = base64.b64encode(f.read()).decode("utf-8") + + self.elements = { + "logo_with_text": Element( + "text", + { + "text": ElementProperty(PropertyType.string), + "logo_path": ElementProperty(PropertyType.string, default_value=logo_base64), + }, + ) + } +``` diff --git a/docs/userman/gui/extension/extension_data.md b/docs/userman/gui/extension/extension_data.md deleted file mode 100644 index adb7694bd..000000000 --- a/docs/userman/gui/extension/extension_data.md +++ /dev/null @@ -1,211 +0,0 @@ -# Using tabular data - -In this section, we will expand the custom element library, initially created in the Static Elements section, by -adding a dynamic custom element. - -This dynamic element will accept a property containing tabular data and display it within a table. When a Python -variable is bound to this property, updates to the variable will immediately reflect in the table content shown on -the front end, ensuring real-time synchronization. - -## Declaring a dynamic element {data-source="gui:doc/extension/example_library/example_library.py#L36"} - -```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 = { - "game_table": Element( - "data", - { - "data": ElementProperty(PropertyType.data), - }, - # The name of the React component (GameTable) that implements this custom - # element, exported as GameTable in front-end/src/index.ts - # react_component="GameTable", - ), - } - def get_name(self) -> str: - return "example" - - def get_elements(self) -> dict: - return self.elements - - def get_scripts(self) -> list[str]: - # Only one JavaScript bundle for this library. - return ["front-end/dist/exampleLibrary.js"] -``` - -The detailed explanation of the code is as follows: - -- The `game_table` element includes a single property: `data`. -- The `data` property has the type `PropertyType.data`, meaning it holds a data value and is dynamic. -- The `get_name` method in the `ExampleLibrary` class returns the name of the library as a string. This name is used - to identify the library within the Taipy GUI framework. -- The `get_elements` method in the `ExampleLibrary` class returns a dictionary of elements that are part of this - library. Each element is defined with its properties and associated React component. - -## Creating the React component {data-source="gui:doc/extension/example_library/front-end/src/GameTable.tsx"} - -The React component for the `game_table` element is defined as follows: - -```jsx -import React, { useEffect, useMemo, useState } from "react"; -import { - createRequestDataUpdateAction, - useDispatch, - useDispatchRequestUpdateOnFirstRender, - useModule, - TaipyDynamicProps, - TableValueType, - RowType, - RowValue, -} from "taipy-gui"; - -interface GameTableProps extends TaipyDynamicProps { - data: TableValueType; -} - -const pageKey = "no-page-key"; - -const GameTable = (props: GameTableProps) => { - const { data, updateVarName = "", updateVars = "", id } = props; - const [value, setValue] = useState>>({}); - const dispatch = useDispatch(); - const module = useModule(); - const refresh = data?.__taipy_refresh !== undefined; - useDispatchRequestUpdateOnFirstRender(dispatch, id, module, updateVars); - - const colsOrder = useMemo(() => { - return Object.keys(value); - }, [value]); - - const rows = useMemo(() => { - const rows: RowType[] = []; - if (value) { - Object.entries(value).forEach(([col, colValues]) => { - colValues.forEach((val, idx) => { - rows[idx] = rows[idx] || {}; - rows[idx][col] = val; - }); - }); - } - return rows; - }, [value]); - - useEffect(() => { - if (refresh || !data || data[pageKey] === undefined) { - dispatch( - createRequestDataUpdateAction( - updateVarName, - id, - module, - colsOrder, - pageKey, - {}, - true, - "ExampleLibrary", - ), - ); - } else { - setValue(data[pageKey]); - } - }, [refresh, data, colsOrder, updateVarName, id, dispatch, module]); - - return ( -
- - - {rows.map((row, index) => ( - - {colsOrder.map((col, cidx) => ( - - ))} - - ))} - -
{row[col]}
-
- ); -}; - -export default GameTable; -``` - -The detailed explanation of the code is as follows: - -- We use the [useDispatch](https://docs.taipy.io/en/latest/refmans/reference_guiext/functions/useDispatch/) hook to - dispatch actions to the store and initiate backend communications. -- Additionally, the [useModule](https://docs.taipy.io/en/latest/refmans/reference_guiext/functions/useModule/) hook - retrieves the page module, enabling correct execution of backend functions. -- To request an update for every dynamic property of an element on initial render, we use the - [useDispatchRequestUpdateOnFirstRender](https://docs.taipy.io/en/latest/refmans/reference_guiext/functions/useDispatchRequestUpdateOnFirstRender/#function-usedispatchrequestupdateonfirstrender) - hook provided by the Taipy GUI Extension API. This hook takes five parameters: - - `dispatch`: The React dispatcher associated with the context. - - `id`: The identifier of the element. - - `context`: The execution context. - - `updateVars`: The content of the `updateVars` property. -- We also dispatch the - [createRequestDataUpdateAction](https://docs.taipy.io/en/latest/refmans/reference_guiext/functions/createRequestUpdateAction/) - hook to create a request data update action, which updates the context by invoking the - [get_data](https://docs.taipy.io/en/latest/refmans/reference/pkg_taipy/pkg_gui/pkg_extension/ElementLibrary/#taipy.gui.extension.ElementLibrary.get_data) - method of the backend library. This invocation triggers an update of front-end elements holding the data. - -The [createRequestDataUpdateAction](https://docs.taipy.io/en/latest/refmans/reference_guiext/functions/createRequestUpdateAction/) -hook accepts eight parameters: - -- `name`: The name of the variable containing the requested data, as received in the property. -- `id`: The identifier of the visual element. -- `context`: The execution context. -- `columns`: The list of columns required by the element emitting this action. -- `pageKey`: The unique identifier for the data received from this action. -- `payload`: The payload, specific to the component type (e.g., table, chart). -- `allData`: A flag indicating if all data is requested. -- `library`: The name of the extension library. - -## 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 JavaScript library. -This is done by adding the export directive in the file `//front-end/src/index.ts`. - -```js -import GameTable from "./GameTable"; - -export { GameTable }; -``` - -## Using the element in the application {data-source="gui:doc/extension/table_chess_game.py"} - -In the example below, we use the `game_table` element to display a chess game board. The board is represented as a -two-dimensional list of strings, where each string represents a chess piece. The board is displayed in a table format -using the `game_table` element. - -```py -from example_library import ExampleLibrary - -from taipy.gui import Gui - -data = [ - ["♜", "♞", "♝", "♛", "♚", "♝", "♞", "♜"] - ["♟", "♟", "♟", "♟", "♟", "♟", "♟", "♟"], - ["", "", "", "", "", "", "", ""], - ["", "", "", "", "", "", "", ""], - ["", "", "", "", "", "", "", ""], - ["", "", "", "", "", "", "", ""], - ["♙", "♙", "♙", "♙", "♙", "♙", "♙", "♙"], - ["♖", "♘", "♗", "♕", "♔", "♗", "♘", "♖"], -] - -page = """ -## Chess Game -<|{data}|example.game_table|> -""" - -if __name__ == "__main__": - Gui(page, libraries=[ExampleLibrary()]).run(title="Chess Game") -``` - -When you run this application, the page displays the element like this: - - diff --git a/docs/userman/gui/extension/extension_list_of_values.md b/docs/userman/gui/extension/extension_list_of_values.md index 091cdb7a9..f950ec620 100644 --- a/docs/userman/gui/extension/extension_list_of_values.md +++ b/docs/userman/gui/extension/extension_list_of_values.md @@ -1,10 +1,153 @@ +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 -!!! warning "Work in Progress" - This section still requires significant work, which is in progress. - At this time, Taipy GUI provides a custom element library example - with lengthy explanations on how to build it.
- Please look into the `doc/extension` directory where Taipy GUI is - installed for more information.
- You can also look at this example directly on - [GitHub](https://github.com/Avaiga/taipy/tree/[BRANCH]/doc/gui/extension). +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 visual element will take a property containing a list of values and render them as a list. + +## 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 = ({ 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 ( +
+
    + {sortedLovList.map((item, index) => ( +
  • + {typeof item.item === "string" ? null : ( + {item.item.text} + )} + {item.id} +
  • + ))} +
+
+ ); +}; + +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 */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: + +
+ + +
Visual labeled list
+
+ diff --git a/docs/userman/gui/extension/dynamic_element/tabular_data_props.md b/docs/userman/gui/extension/extension_tabular_data.md similarity index 83% rename from docs/userman/gui/extension/dynamic_element/tabular_data_props.md rename to docs/userman/gui/extension/extension_tabular_data.md index 043b6e681..f1ee866b6 100644 --- a/docs/userman/gui/extension/dynamic_element/tabular_data_props.md +++ b/docs/userman/gui/extension/extension_tabular_data.md @@ -1,4 +1,4 @@ -The previous section on [Scalar properties](scalar_props.md) shows how to create a dynamic element +The previous section on [Scalar properties](dynamic_element/scalar_props.md) shows how to create a dynamic element that holds a scalar value. However, when dealing with collections of data, such as tabular data, we need a more complex approach to support arrays or tables that can be dynamically updated. @@ -23,15 +23,14 @@ this approach. # Using tabular data In this section, we will expand the dynamic element library, initially created in the -[Scalar properties](scalar_props.md) section, by adding a new dynamic custom element. +[Scalar properties](dynamic_element/scalar_props.md) section, by adding a chessboard element. -This dynamic element will accept a property containing tabular data and display it within a table. -When a Python variable is bound to this property, updates to the variable will immediately reflect -in the table content shown on the page, ensuring real-time synchronization. +This visual element will take a property representing the state of a chess game, +structured as tabular data, and render it as an interactive chessboard. -## Declaring a dynamic element {data-source="gui/extension/example_library/example_library.py#L36"} +## Declaring a dynamic element {data-source="gui:doc/extension/example_library/example_library.py#L43"} Starting from the code mentioned above, here is how you would declare this new element: -```py title="example_library.py" +```python title="example_library.py" from taipy.gui.extension import Element, ElementLibrary, ElementProperty, PropertyType class ExampleLibrary(ElementLibrary): @@ -49,8 +48,8 @@ class ExampleLibrary(ElementLibrary): ), } ``` -The declaration of this dynamic element is very similar to what we created in the -[Scalar properties](scalar_props.md). +The declaration of this element is very similar to what we created in the +[Scalar properties](dynamic_element/scalar_props.md). The detailed explanation of the code is as follows: @@ -63,11 +62,11 @@ The detailed explanation of the code is as follows: that are part of this library. Each element is defined with its properties and associated React component. -## Creating the React component {data-source="gui/extension/example_library/front-end/src/GameTable.tsx"} +## Creating the React component {data-source="gui:doc/extension/example_library/front-end/src/GameTable.tsx"} The React component for the *game_table* element is defined as follows: -```jsx title="GameTable.tsx" linenums="1" +```tsx title="GameTable.tsx" import React, { useEffect, useMemo, useState } from "react"; import { createRequestDataUpdateAction, @@ -152,24 +151,24 @@ export default GameTable; The detailed explanation of the code is as follows: -- We use the [`useDispatch()`](../../../../refmans/reference_guiext/functions/useDispatch.md) hook +- We use the [`useDispatch()`](../../refmans/reference_guiext/functions/useDispatch.md) hook to dispatch actions to the store and initiate backend communications. -- Additionally, the [`useModule()`](../../../../refmans/reference_guiext/functions/useModule.md) +- Additionally, the [`useModule()`](../../refmans/reference_guiext/functions/useModule.md) hook retrieves the page module, enabling correct execution of backend functions. - To request an update for every dynamic property of an element on initial render, we use the - [`useDispatchRequestUpdateOnFirstRender()`](../../../../refmans/reference_guiext/functions/useDispatchRequestUpdateOnFirstRender.md) + [`useDispatchRequestUpdateOnFirstRender()`](../../refmans/reference_guiext/functions/useDispatchRequestUpdateOnFirstRender.md) hook provided by the Taipy GUI Extension API. This hook takes five parameters: - *dispatch*: The React dispatcher associated with the context. - *id*: The identifier of the element. - *context*: The execution context. - *updateVars*: The content of the *updateVars* property. - We also dispatch the - [`createRequestDataUpdateAction()`](../../../../refmans/reference_guiext/functions/createRequestDataUpdateAction.md) + [`createRequestDataUpdateAction()`](../../refmans/reference_guiext/functions/createRequestDataUpdateAction.md) hook to create a request data update action, which updates the context by invoking the `(ElementLibrary.)get_data()^` method of the backend library. This invocation triggers an update of front-end elements holding the data. -The [`createRequestDataUpdateAction()`](../../../../refmans/reference_guiext/functions/createRequestUpdateAction.md) +The [`createRequestDataUpdateAction()`](../../refmans/reference_guiext/functions/createRequestUpdateAction.md) hook accepts eight parameters: - *name*: The name of the variable containing the requested data, as received in the property. @@ -181,18 +180,18 @@ hook accepts eight parameters: - *allData*: A flag indicating if all the data is requested. - *library*: The name of the extension library. -## Exporting the React component {data-source="gui/extension/example_library/front-end/src/index.ts"} +## 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 JavaScript library. This is done by adding the export directive in the file */front-end/src/index.ts*. -```js title="index.ts" +```ts title="index.ts" import GameTable from "./GameTable"; export { GameTable }; ``` -## Using the element {data-source="gui/extension/table_chess_game.py"} +## Using the element {data-source="gui:doc/extension/table_chess_game.py"} In the example below, we use the *game_table* element to display a chess game board. The data is represented as a two-dimensional list of strings, where each string represents a chess @@ -201,7 +200,7 @@ The board is displayed in a table format using the *game_table* element.
We can see how the data property of the control is bound to the Python variable *data*, using the default property syntax. -```py +```python title="table_chess_game.py" data = [ ["♜", "♞", "♝", "♛", "♚", "♝", "♞", "♜"] ["♟", "♟", "♟", "♟", "♟", "♟", "♟", "♟"], diff --git a/docs/userman/gui/extension/index.md b/docs/userman/gui/extension/index.md index 3e61c41fe..888aada6b 100644 --- a/docs/userman/gui/extension/index.md +++ b/docs/userman/gui/extension/index.md @@ -231,6 +231,6 @@ make your way from one example to the next. - [Custom dynamic elements](dynamic_element/index.md) - [Using scalar properties](dynamic_element/scalar_props.md) - [Using List of Values](extension_list_of_values.md) -- [Using tabular data](extension_data.md) +- [Using tabular data](extension_tabular_data.md) - [Accessing assets](extension_assets.md) - [Packaging an element library](extension_packaging.md) diff --git a/docs/userman/gui/extension/visual_label_list-d.png b/docs/userman/gui/extension/visual_label_list-d.png new file mode 100644 index 000000000..b565c3bd2 Binary files /dev/null and b/docs/userman/gui/extension/visual_label_list-d.png differ diff --git a/docs/userman/gui/extension/visual_label_list-l.png b/docs/userman/gui/extension/visual_label_list-l.png new file mode 100644 index 000000000..cd2163e7f Binary files /dev/null and b/docs/userman/gui/extension/visual_label_list-l.png differ diff --git a/mkdocs.yml_template b/mkdocs.yml_template index 5776180ae..a90313384 100644 --- a/mkdocs.yml_template +++ b/mkdocs.yml_template @@ -100,7 +100,8 @@ nav: - "Dynamic Elements": - userman/gui/extension/dynamic_element/index.md - "Scalar properties": userman/gui/extension/dynamic_element/scalar_props.md - - "Tabular data properties": userman/gui/extension/dynamic_element/tabular_data_props.md + - "List of Values Elements": userman/gui/extension/extension_list_of_values.md + - "Tabular Elements": userman/gui/extension/extension_tabular_data.md - "Scenario features": - "Data integration":