Skip to content

Commit 1a060e6

Browse files
authored
Merge pull request #139 from bcdev/clarasb-135-component_visibility
Fix handling of `style` property in `Tabs` component
2 parents 794871e + 594979e commit 1a060e6

5 files changed

Lines changed: 88 additions & 23 deletions

File tree

chartlets.js/CHANGES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
* Added icon support for `Button`, `IconButton` and `Tabs` components.
1010
(#124).
1111

12+
* Fixed handling of `style` prop in `Tabs` component and added prop
13+
`iconPosition`. (#135, #136)
14+
1215
## Version 0.1.7 (from 2025/12/03)
1316

1417
* Updated dependencies

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@ import { Icon } from "./Icon";
1515
import { isString } from "@/utils/isString";
1616
import { isComponentState } from "@/types/state/component";
1717

18-
interface TabState {
18+
interface TabState extends ComponentState {
1919
type: "Tab";
2020
label?: string;
2121
icon?: string;
22+
iconPosition?: "bottom" | "end" | "start" | "top";
2223
disabled?: boolean;
2324
children?: ComponentProps[];
2425
}
@@ -50,20 +51,22 @@ export function Tabs({
5051
}
5152
};
5253
return (
53-
<MuiBox sx={{ width: "100%" }}>
54+
<MuiBox sx={{ width: "100%" }} style={style}>
5455
<MuiBox sx={{ borderBottom: 1, borderColor: "divider" }}>
55-
<MuiTabs id={id} style={style} value={value} onChange={handleChange}>
56+
<MuiTabs id={id} value={value} onChange={handleChange}>
5657
{tabItems?.map((tab, index) => {
5758
const tabState = isComponentState(tab)
5859
? (tab as TabState)
5960
: undefined;
6061
return (
6162
<MuiTab
6263
key={index}
64+
style={tabState?.style}
6365
label={tabState ? tabState.label : isString(tab) ? tab : ""}
6466
icon={
6567
tabState && tabState.icon && <Icon iconName={tabState.icon} />
6668
}
69+
iconPosition={tabState?.iconPosition}
6770
disabled={disabled || (tabState && tabState.disabled)}
6871
/>
6972
);
@@ -78,7 +81,7 @@ export function Tabs({
7881
key={index}
7982
type={type}
8083
onChange={onChange}
81-
children={tabState?.children ?? undefined}
84+
children={tabState?.children}
8285
/>
8386
)
8487
);

chartlets.py/CHANGES.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
* Added `size` and removed `variant` property from `IconButton`
44
component to align with component in chartlets.js. (#124)
55

6+
* Added `iconPosition` to `Tabs` Component. (#135, #136)
7+
68
## Version 0.1.7 (from 2025/12/03)
79

810
* Updated dependencies
@@ -14,10 +16,10 @@
1416

1517
## Version 0.1.5 (from 2025/03/21)
1618

17-
* Add `multiple` property for `Select` component to enable the
19+
* Added `multiple` property for `Select` component to enable the selection
1820
of multiple elements.
1921

20-
* Add support for `Python 3.13`
22+
* Added support for `Python 3.13`
2123

2224

2325
## Version 0.1.4 (from 2025/03/06)

chartlets.py/chartlets/components/tabs.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ class Tab(Component):
1616
icon: str | None = None
1717
"""The tab icon's name."""
1818

19+
iconPosition: str | None = None
20+
""" The position of the icon relative to the label.
21+
One of "bottom" | "end" | "start" | "top".
22+
Defaults to "top".
23+
"""
24+
1925
label: str | None = None
2026
"""The tab label."""
2127

chartlets.py/demo/my_extension/my_panel_8.py

Lines changed: 68 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,15 @@
55
import altair as alt
66

77
from chartlets import Component, Input, State, Output
8-
from chartlets.components import (Tabs, Tab, Typography, Box,
9-
VegaChart, Table)
8+
from chartlets.components import (
9+
Tabs,
10+
Tab,
11+
Typography,
12+
Box,
13+
VegaChart,
14+
Table,
15+
Button,
16+
)
1017
from chartlets.components.table import TableColumn, TableRow
1118

1219
from server.context import Context
@@ -41,25 +48,48 @@ def render_panel(
4148
["3", "Peter", "Jones", 40],
4249
]
4350

44-
table = Table(id="table", rows=rows, columns=columns, hover=True)
51+
open_button = Button(
52+
id="open_button", text="Show component!", style={"margin": "20px"}
53+
)
54+
55+
table = Table(
56+
id="table",
57+
rows=rows,
58+
columns=columns,
59+
hover=True,
60+
style={"width": "100%", "padding": "2px"},
61+
)
4562

46-
info_text = Typography(id="info_text", children=["This is a text."])
4763
chart = VegaChart(
48-
id="chart", chart=(
49-
alt.Chart(dataset)
50-
.mark_bar()
51-
.encode(
52-
x=alt.X("x:N", title="x"),
53-
y=alt.Y("a:Q", title="a"))
54-
.properties(width=290, height=300, title="Vega charts")
55-
), style={"flexGrow": 1}
64+
id="chart",
65+
chart=(
66+
alt.Chart(dataset)
67+
.mark_bar()
68+
.encode(x=alt.X("x:N", title="x"), y=alt.Y("a:Q", title="a"))
69+
.properties(width=290, height=300, title="Vega charts")
70+
),
71+
style={"flexGrow": 1, "margin": "10px"},
5672
)
5773

58-
tab1 = Tab(id = "tab1", label="Tab 1", children=[table])
59-
tab2 = Tab(id = "tab2", label="Tab 2", children=[info_text])
60-
tab3 = Tab(id="tab3", label="Tab 3", children=[chart])
74+
tab1 = Tab(
75+
id="tab1",
76+
label="Tab 1",
77+
children=[table],
78+
style={"backgroundColor": "darkblue", "padding": "1px"},
79+
)
80+
tab2 = Tab(id="tab2", label="Tab 2", children=["This is a text."], disabled=True)
81+
tab3 = Tab(
82+
id="tab3",
83+
label="Tab 3",
84+
children=[chart],
85+
)
6186

62-
tabs = Tabs(id = "tabs", value = 0, children=[tab1,tab2,tab3])
87+
tabs = Tabs(
88+
id="tabs",
89+
value=0,
90+
children=[tab1, tab2, tab3],
91+
style={"visibility": "hidden"},
92+
)
6393

6494
return Box(
6595
style={
@@ -68,6 +98,27 @@ def render_panel(
6898
"width": "100%",
6999
"height": "100%",
70100
},
71-
children=[ tabs ],
101+
children=[open_button, tabs],
72102
)
73103

104+
105+
# noinspection PyUnusedLocal
106+
@panel.callback(
107+
Input("open_button", "clicked"),
108+
Input("tabs", "style"),
109+
Output("tabs", "style"),
110+
Output("open_button", "text"),
111+
)
112+
def tabs_on_open(ctx: Context, button, style) -> tuple[dict, str]:
113+
visibility = style["visibility"]
114+
115+
if visibility == "hidden":
116+
return (
117+
{**style, "visibility": "visible"},
118+
"Hide component!",
119+
)
120+
else:
121+
return (
122+
{**style, "visibility": "hidden"},
123+
"Show component!",
124+
)

0 commit comments

Comments
 (0)