Skip to content

Commit de1922d

Browse files
authored
Merge pull request #129 from bcdev/clarasb-xxx-add_demo_panel_8
Modify `Tabs` and create demo panel
2 parents 3403cfd + 19ad7ec commit de1922d

File tree

4 files changed

+109
-11
lines changed

4 files changed

+109
-11
lines changed

chartlets.js/CHANGES.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@
1616

1717
* Typology component now allows color and text arguments.
1818
If a user uses text and children, the text argument replaces the
19-
children.
19+
children.
2020

21+
* Applied changes to the return value of `Tabs` component and added
22+
demo panel H, that showcases the use of `Tabs` component. (#129).
23+
2124
## Version 0.1.6 (from 2025/06/18)
2225

2326
* Implemented dynamic resizing for Vega Charts when the side panel's

chartlets.js/packages/lib/src/plugins/mui/Tabs.tsx

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
import MuiBox from "@mui/material/Box";
12
import MuiIcon from "@mui/material/Icon";
23
import MuiTabs from "@mui/material/Tabs";
34
import MuiTab from "@mui/material/Tab";
45

56
import type { ComponentProps, ComponentState } from "@/index";
67
import type { SyntheticEvent } from "react";
8+
import { Box } from "@/plugins/mui/Box";
79
import { isString } from "@/utils/isString";
810
import { isComponentState } from "@/types/state/component";
911

@@ -12,6 +14,7 @@ interface TabState {
1214
label?: string;
1315
icon?: string;
1416
disabled?: boolean;
17+
children?: ComponentProps[];
1518
}
1619

1720
interface TabsState extends ComponentState {
@@ -41,19 +44,40 @@ export function Tabs({
4144
}
4245
};
4346
return (
44-
<MuiTabs id={id} style={style} value={value} onChange={handleChange}>
45-
{tabItems?.map((tab) => {
47+
<MuiBox sx={{ width: "100%" }}>
48+
<MuiBox sx={{ borderBottom: 1, borderColor: "divider" }}>
49+
<MuiTabs id={id} style={style} value={value} onChange={handleChange}>
50+
{tabItems?.map((tab, index) => {
51+
const tabState = isComponentState(tab)
52+
? (tab as TabState)
53+
: undefined;
54+
return (
55+
<MuiTab
56+
key={index}
57+
label={tabState ? tabState.label : isString(tab) ? tab : ""}
58+
icon={
59+
tabState &&
60+
tabState.icon && <MuiIcon>{tabState.icon}</MuiIcon>
61+
}
62+
disabled={disabled || (tabState && tabState.disabled)}
63+
/>
64+
);
65+
})}
66+
</MuiTabs>
67+
</MuiBox>
68+
{tabItems?.map((tab, index) => {
4669
const tabState = isComponentState(tab) ? (tab as TabState) : undefined;
4770
return (
48-
<MuiTab
49-
label={tabState ? tabState.label : isString(tab) ? tab : ""}
50-
icon={
51-
tabState && tabState.icon && <MuiIcon>{tabState.icon}</MuiIcon>
52-
}
53-
disabled={disabled || (tabState && tabState.disabled)}
54-
/>
71+
value === index && (
72+
<Box
73+
key={index}
74+
type={type}
75+
onChange={onChange}
76+
children={tabState?.children ?? undefined}
77+
/>
78+
)
5579
);
5680
})}
57-
</MuiTabs>
81+
</MuiBox>
5882
);
5983
}

chartlets.py/demo/my_extension/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from .my_panel_5 import panel as my_panel_5
77
from .my_panel_6 import panel as my_panel_6
88
from .my_panel_7 import panel as my_panel_7
9+
from .my_panel_8 import panel as my_panel_8
910

1011

1112
ext = Extension(__name__)
@@ -16,3 +17,4 @@
1617
ext.add(my_panel_5)
1718
ext.add(my_panel_6)
1819
ext.add(my_panel_7)
20+
ext.add(my_panel_8)
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import altair as alt
2+
3+
from chartlets import Component, Input, State, Output
4+
from chartlets.components import (Tabs, Tab, Typography, Box,
5+
VegaChart, Table)
6+
from chartlets.components.table import TableColumn, TableRow
7+
8+
from server.context import Context
9+
from server.panel import Panel
10+
11+
12+
panel = Panel(__name__, title="Panel H")
13+
14+
15+
@panel.layout(State("@app", "selectedDatasetId"))
16+
def render_panel(
17+
ctx: Context,
18+
selected_dataset_id: str = "",
19+
) -> Component:
20+
dataset = ctx.datasets.get(selected_dataset_id)
21+
22+
columns: list[TableColumn] = [
23+
{"id": "id", "label": "ID", "sortDirection": "desc"},
24+
{
25+
"id": "firstName",
26+
"label": "First Name",
27+
"align": "left",
28+
"sortDirection": "desc",
29+
},
30+
{"id": "lastName", "label": "Last Name", "align": "center"},
31+
{"id": "age", "label": "Age"},
32+
]
33+
34+
rows: TableRow = [
35+
["1", "John", "Doe", 30],
36+
["2", "Jane", "Smith", 25],
37+
["3", "Peter", "Jones", 40],
38+
]
39+
40+
table = Table(id="table", rows=rows, columns=columns, hover=True)
41+
42+
info_text = Typography(id="info_text", children=["This is a text."])
43+
chart = VegaChart(
44+
id="chart", chart=(
45+
alt.Chart(dataset)
46+
.mark_bar()
47+
.encode(
48+
x=alt.X("x:N", title="x"),
49+
y=alt.Y("a:Q", title="a"))
50+
.properties(width=290, height=300, title="Vega charts")
51+
), style={"flexGrow": 1}
52+
)
53+
54+
tab1 = Tab(id = "tab1", label="Tab 1", children=[table])
55+
tab2 = Tab(id = "tab2", label="Tab 2", children=[info_text])
56+
tab3 = Tab(id="tab3", label="Tab 3", children=[chart])
57+
58+
tabs = Tabs(id = "tabs", value = 0, children=[tab1,tab2,tab3])
59+
60+
return Box(
61+
style={
62+
"display": "flex",
63+
"flexDirection": "column",
64+
"width": "100%",
65+
"height": "100%",
66+
},
67+
children=[ tabs ],
68+
)
69+

0 commit comments

Comments
 (0)