From 53d2885b55a761366ff749e88f95969f1e87653b Mon Sep 17 00:00:00 2001 From: clarasb Date: Fri, 14 Nov 2025 11:51:14 +0100 Subject: [PATCH 1/5] add panel H --- chartlets.py/demo/my_extension/__init__.py | 2 + chartlets.py/demo/my_extension/my_panel_8.py | 50 ++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 chartlets.py/demo/my_extension/my_panel_8.py diff --git a/chartlets.py/demo/my_extension/__init__.py b/chartlets.py/demo/my_extension/__init__.py index 5c9f47d..2cdb6cd 100644 --- a/chartlets.py/demo/my_extension/__init__.py +++ b/chartlets.py/demo/my_extension/__init__.py @@ -6,6 +6,7 @@ from .my_panel_5 import panel as my_panel_5 from .my_panel_6 import panel as my_panel_6 from .my_panel_7 import panel as my_panel_7 +from .my_panel_8 import panel as my_panel_8 ext = Extension(__name__) @@ -16,3 +17,4 @@ ext.add(my_panel_5) ext.add(my_panel_6) ext.add(my_panel_7) +ext.add(my_panel_8) diff --git a/chartlets.py/demo/my_extension/my_panel_8.py b/chartlets.py/demo/my_extension/my_panel_8.py new file mode 100644 index 0000000..da9f6ea --- /dev/null +++ b/chartlets.py/demo/my_extension/my_panel_8.py @@ -0,0 +1,50 @@ +import altair as alt +import pandas as pd +from chartlets import Component, Input, State, Output +from chartlets.components import Tabs, Tab, Typography, Box, VegaChart + +from server.context import Context +from server.panel import Panel + + +panel = Panel(__name__, title="Panel H") + + +@panel.layout(State("@app", "selectedDatasetId")) +def render_panel( + ctx: Context, + selected_dataset_id: str = "", +) -> Component: + dataset = ctx.datasets.get(selected_dataset_id) + + c = ( + alt.Chart(dataset) + .mark_bar() + .encode( + x=alt.X("x:N", title="x"), + y=alt.Y("a:Q", title="a")) + ) + + chart = VegaChart( + id="chart1", chart=c, style={"flexGrow": 1} + ) + + info_text = Typography(id="info_text", children=["hallo"]) + + tab1=Tab(id = "tab1",label="Plot 1", children=["Hallo"]) + tab2=Tab(id = "tab2",label="Plot 2", children=[info_text]) + tab3 = Tab(id="tab3", label="Plot 3", children=[chart]) + + select = Tabs(id = "tab", value = 0, children=[tab1,tab2,tab3]) + + + return Box( + style={ + "display": "flex", + "flexDirection": "column", + "width": "100%", + "height": "100%", + }, + children=[chart, info_text, select,tab2], + ) + From f03d85e7d38965358caa6bb8307daf0bac52d9b5 Mon Sep 17 00:00:00 2001 From: clarasb Date: Fri, 14 Nov 2025 17:58:14 +0100 Subject: [PATCH 2/5] update Tabs component --- .../packages/lib/src/plugins/mui/Tabs.tsx | 42 +++++++++++----- chartlets.py/demo/my_extension/my_panel_8.py | 49 +++++++++++++------ 2 files changed, 65 insertions(+), 26 deletions(-) diff --git a/chartlets.js/packages/lib/src/plugins/mui/Tabs.tsx b/chartlets.js/packages/lib/src/plugins/mui/Tabs.tsx index 355c304..523e7e9 100644 --- a/chartlets.js/packages/lib/src/plugins/mui/Tabs.tsx +++ b/chartlets.js/packages/lib/src/plugins/mui/Tabs.tsx @@ -2,8 +2,9 @@ import MuiIcon from "@mui/material/Icon"; import MuiTabs from "@mui/material/Tabs"; import MuiTab from "@mui/material/Tab"; -import type { ComponentProps, ComponentState } from "@/index"; +import { type ComponentProps, type ComponentState } from "@/index"; import type { SyntheticEvent } from "react"; +import { Box } from "@/plugins/mui/Box"; import { isString } from "@/utils/isString"; import { isComponentState } from "@/types/state/component"; @@ -12,6 +13,7 @@ interface TabState { label?: string; icon?: string; disabled?: boolean; + children?: ComponentProps[]; } interface TabsState extends ComponentState { @@ -41,19 +43,37 @@ export function Tabs({ } }; return ( - - {tabItems?.map((tab) => { +
+ + {tabItems?.map((tab, index) => { + const tabState = isComponentState(tab) + ? (tab as TabState) + : undefined; + return ( + {tabState.icon} + } + disabled={disabled || (tabState && tabState.disabled)} + /> + ); + })} + + {tabItems?.map((tab, index) => { const tabState = isComponentState(tab) ? (tab as TabState) : undefined; return ( - {tabState.icon} - } - disabled={disabled || (tabState && tabState.disabled)} - /> + value === index && ( + + ) ); })} - +
); } diff --git a/chartlets.py/demo/my_extension/my_panel_8.py b/chartlets.py/demo/my_extension/my_panel_8.py index da9f6ea..be7a7a8 100644 --- a/chartlets.py/demo/my_extension/my_panel_8.py +++ b/chartlets.py/demo/my_extension/my_panel_8.py @@ -1,7 +1,9 @@ import altair as alt -import pandas as pd + from chartlets import Component, Input, State, Output -from chartlets.components import Tabs, Tab, Typography, Box, VegaChart +from chartlets.components import (Tabs, Tab, Typography, Box, + VegaChart, Table) +from chartlets.components.table import TableColumn, TableRow from server.context import Context from server.panel import Panel @@ -17,26 +19,43 @@ def render_panel( ) -> Component: dataset = ctx.datasets.get(selected_dataset_id) - c = ( + columns: list[TableColumn] = [ + {"id": "id", "label": "ID", "sortDirection": "desc"}, + { + "id": "firstName", + "label": "First Name", + "align": "left", + "sortDirection": "desc", + }, + {"id": "lastName", "label": "Last Name", "align": "center"}, + {"id": "age", "label": "Age"}, + ] + + rows: TableRow = [ + ["1", "John", "Doe", 30], + ["2", "Jane", "Smith", 25], + ["3", "Peter", "Jones", 40], + ] + + table = Table(id="table", rows=rows, columns=columns, hover=True) + + info_text = Typography(id="info_text", children=["This is a text."]) + chart = VegaChart( + id="chart", chart=( alt.Chart(dataset) .mark_bar() .encode( x=alt.X("x:N", title="x"), y=alt.Y("a:Q", title="a")) + .properties(width=290, height=300, title="Vega charts") + ), style={"flexGrow": 1} ) - chart = VegaChart( - id="chart1", chart=c, style={"flexGrow": 1} - ) - - info_text = Typography(id="info_text", children=["hallo"]) - - tab1=Tab(id = "tab1",label="Plot 1", children=["Hallo"]) - tab2=Tab(id = "tab2",label="Plot 2", children=[info_text]) - tab3 = Tab(id="tab3", label="Plot 3", children=[chart]) - - select = Tabs(id = "tab", value = 0, children=[tab1,tab2,tab3]) + tab1 = Tab(id = "tab1", label="Tab 1", children=[table]) + tab2 = Tab(id = "tab2", label="Tab 2", children=[info_text]) + tab3 = Tab(id="tab3", label="Tab 3", children=[chart]) + tabs = Tabs(id = "tab", value = 0, children=[tab1,tab2,tab3]) return Box( style={ @@ -45,6 +64,6 @@ def render_panel( "width": "100%", "height": "100%", }, - children=[chart, info_text, select,tab2], + children=[ tabs ], ) From cbab03299afa5f9ee05dfa8f48bd357094ea5cfb Mon Sep 17 00:00:00 2001 From: clarasb Date: Fri, 14 Nov 2025 18:02:52 +0100 Subject: [PATCH 3/5] fix typos --- chartlets.js/packages/lib/src/plugins/mui/Tabs.tsx | 2 +- chartlets.py/demo/my_extension/my_panel_8.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/chartlets.js/packages/lib/src/plugins/mui/Tabs.tsx b/chartlets.js/packages/lib/src/plugins/mui/Tabs.tsx index 523e7e9..e819551 100644 --- a/chartlets.js/packages/lib/src/plugins/mui/Tabs.tsx +++ b/chartlets.js/packages/lib/src/plugins/mui/Tabs.tsx @@ -2,7 +2,7 @@ import MuiIcon from "@mui/material/Icon"; import MuiTabs from "@mui/material/Tabs"; import MuiTab from "@mui/material/Tab"; -import { type ComponentProps, type ComponentState } from "@/index"; +import type { ComponentProps, ComponentState } from "@/index"; import type { SyntheticEvent } from "react"; import { Box } from "@/plugins/mui/Box"; import { isString } from "@/utils/isString"; diff --git a/chartlets.py/demo/my_extension/my_panel_8.py b/chartlets.py/demo/my_extension/my_panel_8.py index be7a7a8..ac3907b 100644 --- a/chartlets.py/demo/my_extension/my_panel_8.py +++ b/chartlets.py/demo/my_extension/my_panel_8.py @@ -55,7 +55,7 @@ def render_panel( tab2 = Tab(id = "tab2", label="Tab 2", children=[info_text]) tab3 = Tab(id="tab3", label="Tab 3", children=[chart]) - tabs = Tabs(id = "tab", value = 0, children=[tab1,tab2,tab3]) + tabs = Tabs(id = "tabs", value = 0, children=[tab1,tab2,tab3]) return Box( style={ From 4f20f0981dcf6350920da7dc3ec048b76d514894 Mon Sep 17 00:00:00 2001 From: clarasb Date: Fri, 14 Nov 2025 18:09:15 +0100 Subject: [PATCH 4/5] update Changes.md --- chartlets.js/CHANGES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/chartlets.js/CHANGES.md b/chartlets.js/CHANGES.md index 26589b7..53bcd97 100644 --- a/chartlets.js/CHANGES.md +++ b/chartlets.js/CHANGES.md @@ -11,6 +11,9 @@ * Typology component now allows color and text arguments. If a user uses text and children, the text argument replaces the children. + +* Applied changes to the return value of `Tabs` component and added + demo panel H, that showcases the use of `Tabs` component. (#129). ## Version 0.1.6 (from 2025/06/18) From 19ad7ec9339eeb52ced0d7b918d68c3b32a40768 Mon Sep 17 00:00:00 2001 From: clarasb Date: Fri, 28 Nov 2025 15:53:14 +0100 Subject: [PATCH 5/5] update Tabs component - add MuiBox --- .../packages/lib/src/plugins/mui/Tabs.tsx | 42 ++++++++++--------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/chartlets.js/packages/lib/src/plugins/mui/Tabs.tsx b/chartlets.js/packages/lib/src/plugins/mui/Tabs.tsx index e819551..bf3367a 100644 --- a/chartlets.js/packages/lib/src/plugins/mui/Tabs.tsx +++ b/chartlets.js/packages/lib/src/plugins/mui/Tabs.tsx @@ -1,3 +1,4 @@ +import MuiBox from "@mui/material/Box"; import MuiIcon from "@mui/material/Icon"; import MuiTabs from "@mui/material/Tabs"; import MuiTab from "@mui/material/Tab"; @@ -43,24 +44,27 @@ export function Tabs({ } }; return ( -
- - {tabItems?.map((tab, index) => { - const tabState = isComponentState(tab) - ? (tab as TabState) - : undefined; - return ( - {tabState.icon} - } - disabled={disabled || (tabState && tabState.disabled)} - /> - ); - })} - + + + + {tabItems?.map((tab, index) => { + const tabState = isComponentState(tab) + ? (tab as TabState) + : undefined; + return ( + {tabState.icon} + } + disabled={disabled || (tabState && tabState.disabled)} + /> + ); + })} + + {tabItems?.map((tab, index) => { const tabState = isComponentState(tab) ? (tab as TabState) : undefined; return ( @@ -74,6 +78,6 @@ export function Tabs({ ) ); })} -
+ ); }