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"], + }, + )