diff --git a/chartlets.js/CHANGES.md b/chartlets.js/CHANGES.md
index 7e5fd11f..5e0d1532 100644
--- a/chartlets.js/CHANGES.md
+++ b/chartlets.js/CHANGES.md
@@ -38,6 +38,7 @@
- using `return` object with `schema` property for callback return values
* New (MUI) components
+ - `Divider`
- `LinearProgress`
- `RadioGroup` and `Radio`
- `Switch`
diff --git a/chartlets.js/packages/lib/src/plugins/mui/Divider.test.tsx b/chartlets.js/packages/lib/src/plugins/mui/Divider.test.tsx
new file mode 100644
index 00000000..d623c025
--- /dev/null
+++ b/chartlets.js/packages/lib/src/plugins/mui/Divider.test.tsx
@@ -0,0 +1,22 @@
+import { describe, it, expect } from "vitest";
+import { render, screen } from "@testing-library/react";
+import type { ComponentChangeHandler } from "@/types/state/event";
+import { Divider } from "./Divider";
+
+describe("Divider", () => {
+ it("should render the Box component", () => {
+ const onChange: ComponentChangeHandler = () => {};
+ render(
+ ,
+ );
+ // to inspect rendered component, do:
+ // expect(document.querySelector("#bx")).toEqual({});
+ expect(screen.getByText("Section 1")).not.toBeUndefined();
+ });
+});
diff --git a/chartlets.js/packages/lib/src/plugins/mui/Divider.tsx b/chartlets.js/packages/lib/src/plugins/mui/Divider.tsx
new file mode 100644
index 00000000..bd54cfe3
--- /dev/null
+++ b/chartlets.js/packages/lib/src/plugins/mui/Divider.tsx
@@ -0,0 +1,39 @@
+import type { ElementType } from "react";
+import MuiDivider from "@mui/material/Divider";
+
+import type { ComponentState, ComponentProps } from "@/index";
+import { Children } from "@/index";
+
+interface DividerState extends ComponentState {
+ orientation?: "horizontal" | "vertical";
+ variant?: "fullWidth" | "inset" | "middle";
+ flexItem?: boolean;
+ textAlign?: "left" | "center" | "right";
+ component?: ElementType;
+}
+
+interface DividerProps extends ComponentProps, DividerState {}
+
+export const Divider = ({
+ id,
+ style,
+ orientation,
+ variant,
+ flexItem,
+ textAlign,
+ children: nodes,
+ onChange,
+}: DividerProps) => {
+ return (
+
+ {nodes && nodes.length && }
+
+ );
+};
diff --git a/chartlets.js/packages/lib/src/plugins/mui/index.ts b/chartlets.js/packages/lib/src/plugins/mui/index.ts
index f59a71ca..6d430bdc 100644
--- a/chartlets.js/packages/lib/src/plugins/mui/index.ts
+++ b/chartlets.js/packages/lib/src/plugins/mui/index.ts
@@ -3,6 +3,7 @@ import { Box } from "./Box";
import { Button } from "./Button";
import { Checkbox } from "./Checkbox";
import { CircularProgress } from "./CircularProgress";
+import { Divider } from "./Divider";
import { IconButton } from "./IconButton";
import { LinearProgress } from "./LinearProgress";
import { RadioGroup } from "./RadioGroup";
@@ -19,6 +20,7 @@ export default function mui(): Plugin {
["Button", Button],
["Checkbox", Checkbox],
["CircularProgress", CircularProgress],
+ ["Divider", Divider],
["IconButton", IconButton],
["LinearProgress", LinearProgress],
["RadioGroup", RadioGroup],
diff --git a/chartlets.py/CHANGES.md b/chartlets.py/CHANGES.md
index 6dd0fc46..5bccfbfa 100644
--- a/chartlets.py/CHANGES.md
+++ b/chartlets.py/CHANGES.md
@@ -19,11 +19,12 @@
* Added `tooltip` property to interactive components.
* New components
- - `Switch`
+ - `Divider`
- `RadioGroup` and `Radio`
- - `Tabs`
+ - `Switch`
- `Slider`
-
+ - `Tabs` and `Tab`
+
## Version 0.0.29 (from 2024/11/26)
* Fixed a bug that prevents using annotations of type `dict` or `dict[str, T]`.
diff --git a/chartlets.py/chartlets/components/__init__.py b/chartlets.py/chartlets/components/__init__.py
index 615d95c0..ac2142de 100644
--- a/chartlets.py/chartlets/components/__init__.py
+++ b/chartlets.py/chartlets/components/__init__.py
@@ -3,6 +3,7 @@
from .button import IconButton
from .checkbox import Checkbox
from .charts.vega import VegaChart
+from .divider import Divider
from .progress import CircularProgress
from .progress import CircularProgressWithLabel
from .progress import LinearProgress
diff --git a/chartlets.py/chartlets/components/divider.py b/chartlets.py/chartlets/components/divider.py
new file mode 100644
index 00000000..4f70f5f1
--- /dev/null
+++ b/chartlets.py/chartlets/components/divider.py
@@ -0,0 +1,28 @@
+from dataclasses import dataclass
+from typing import Literal
+
+from chartlets import Container
+
+
+@dataclass(frozen=True)
+class Divider(Container):
+ """The `Divider` component provides a thin,
+ unobtrusive line for grouping elements to reinforce visual hierarchy.
+ """
+
+ orientation: Literal["horizontal", "vertical"] | None = None
+ """The orientation. Can be `horizontal` (default) or `vertical`."""
+
+ variant: Literal["fullWidth", "inset", "middle"] | None = None
+ """The variant. One of `fullWidth ` (default), `inset`, and `middle`."""
+
+ textAlign: Literal["left", "center", "right"] | None = None
+ """Use the `textAlign` prop to align elements that are
+ wrapped by the divider. One of `left`, `center` (default), and `right`.
+ """
+
+ flexItem: bool | None = None
+ """Use the `flexItem` prop to display the divider when it's being
+ used in a flex container.
+ """
+
diff --git a/chartlets.py/demo/my_extension/my_panel_3.py b/chartlets.py/demo/my_extension/my_panel_3.py
index e2a91306..36492cc3 100644
--- a/chartlets.py/demo/my_extension/my_panel_3.py
+++ b/chartlets.py/demo/my_extension/my_panel_3.py
@@ -1,5 +1,5 @@
from chartlets import Component, Input, State, Output
-from chartlets.components import Box, Select, Checkbox, Typography
+from chartlets.components import Box, Divider, Select, Checkbox, Typography
from server.context import Context
from server.panel import Panel
@@ -42,6 +42,8 @@ def render_panel(
id="info_text", children=update_info_text(ctx, dataset_id, opaque, color)
)
+ divider = Divider(style={"paddingTop": "10px", "paddingBottom": "10px"})
+
return Box(
style={
"display": "flex",
@@ -50,7 +52,7 @@ def render_panel(
"height": "100%",
"gap": "6px",
},
- children=[opaque_checkbox, color_select, info_text],
+ children=[opaque_checkbox, color_select, divider, info_text],
)
diff --git a/chartlets.py/tests/components/divider_test.py b/chartlets.py/tests/components/divider_test.py
new file mode 100644
index 00000000..ca877039
--- /dev/null
+++ b/chartlets.py/tests/components/divider_test.py
@@ -0,0 +1,22 @@
+from chartlets.components import Divider
+from tests.component_test import make_base
+
+
+class DividerTest(make_base(Divider)):
+
+ def test_is_json_serializable(self):
+ self.assert_is_json_serializable(
+ self.cls(
+ textAlign="center",
+ variant="middle",
+ flexItem=True,
+ children=["Options"],
+ ),
+ {
+ "type": "Divider",
+ "textAlign": "center",
+ "variant": "middle",
+ "flexItem": True,
+ "children": ["Options"],
+ },
+ )