From c618a64c84eb9914f432ae9c0d98f9168132f02d Mon Sep 17 00:00:00 2001 From: Norman Fomferra Date: Mon, 25 Nov 2024 09:46:15 +0100 Subject: [PATCH] Added component `IconButton` and enhanced other components' attributes. --- chartlets.js/CHANGES.md | 4 ++ chartlets.js/package-lock.json | 4 +- chartlets.js/package.json | 2 +- chartlets.js/src/lib/components/Box.tsx | 20 +++++-- chartlets.js/src/lib/components/Button.tsx | 22 ++++++- .../src/lib/components/IconButton.tsx | 57 +++++++++++++++++++ .../src/lib/components/Typography.tsx | 2 +- chartlets.js/src/lib/index.ts | 6 +- chartlets.js/src/lib/types/state/component.ts | 1 + chartlets.py/CHANGES.md | 2 + chartlets.py/chartlets/components/__init__.py | 1 + chartlets.py/chartlets/components/button.py | 41 +++++++++++++ chartlets.py/chartlets/version.py | 2 +- 13 files changed, 152 insertions(+), 12 deletions(-) create mode 100644 chartlets.js/src/lib/components/IconButton.tsx diff --git a/chartlets.js/CHANGES.md b/chartlets.js/CHANGES.md index c33ad80f..4b44b314 100644 --- a/chartlets.js/CHANGES.md +++ b/chartlets.js/CHANGES.md @@ -1,3 +1,7 @@ +## Version 0.0.27 (from 2024/11/25) + +* Added component `IconButton` and enhanced other components' attributes. + ## Version 0.0.26 (from 2024/11/23) * Channels such as `Input`, `State`, `Output` no longer have a `link` property. diff --git a/chartlets.js/package-lock.json b/chartlets.js/package-lock.json index 522f6bbe..7e64c293 100644 --- a/chartlets.js/package-lock.json +++ b/chartlets.js/package-lock.json @@ -1,12 +1,12 @@ { "name": "chartlets", - "version": "0.0.26", + "version": "0.0.27", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "chartlets", - "version": "0.0.26", + "version": "0.0.27", "license": "MIT", "dependencies": { "@emotion/react": "^11.13.3", diff --git a/chartlets.js/package.json b/chartlets.js/package.json index f84bfaf8..5ef47e69 100644 --- a/chartlets.js/package.json +++ b/chartlets.js/package.json @@ -1,6 +1,6 @@ { "name": "chartlets", - "version": "0.0.26", + "version": "0.0.27", "description": "An experimental library for integrating interactive charts into existing JavaScript applications.", "type": "module", "files": [ diff --git a/chartlets.js/src/lib/components/Box.tsx b/chartlets.js/src/lib/components/Box.tsx index b6335544..cbd3a15f 100644 --- a/chartlets.js/src/lib/components/Box.tsx +++ b/chartlets.js/src/lib/components/Box.tsx @@ -1,17 +1,27 @@ import MuiBox from "@mui/material/Box"; +import type { ElementType } from "react"; import type { ComponentState } from "@/lib/types/state/component"; -import { Children } from "../component/Children"; import type { ComponentProps } from "@/lib/component/Component"; +import { Children } from "@/lib/component/Children"; -interface BoxState extends ComponentState {} +interface BoxState extends ComponentState { + component?: ElementType; +} interface BoxProps extends ComponentProps, BoxState {} -export function Box({ id, style, children, onChange }: BoxProps) { +export function Box({ + id, + style, + color, + component, + children: nodes, + onChange, +}: BoxProps) { return ( - - + + ); } diff --git a/chartlets.js/src/lib/components/Button.tsx b/chartlets.js/src/lib/components/Button.tsx index 2f5f40a4..0dba0772 100644 --- a/chartlets.js/src/lib/components/Button.tsx +++ b/chartlets.js/src/lib/components/Button.tsx @@ -1,11 +1,23 @@ import { type MouseEvent } from "react"; import MuiButton from "@mui/material/Button"; +import MuiIcon from "@mui/material/Icon"; import { type ComponentState } from "@/lib/types/state/component"; import type { ComponentProps } from "@/lib/component/Component"; interface ButtonState extends ComponentState { text?: string; + startIcon?: string; + endIcon?: string; + variant?: "contained" | "outlined" | "text"; + color?: + | "inherit" + | "primary" + | "secondary" + | "success" + | "error" + | "info" + | "warning"; } interface ButtonProps extends ComponentProps, ButtonState {} @@ -15,8 +27,12 @@ export function Button({ id, name, style, - text, + variant, + color, disabled, + text, + startIcon, + endIcon, onChange, }: ButtonProps) { const handleClick = (_event: MouseEvent) => { @@ -34,7 +50,11 @@ export function Button({ id={id} name={name} style={style} + variant={variant} + color={color} disabled={disabled} + startIcon={startIcon && {startIcon}} + endIcon={endIcon && {endIcon}} onClick={handleClick} > {text} diff --git a/chartlets.js/src/lib/components/IconButton.tsx b/chartlets.js/src/lib/components/IconButton.tsx new file mode 100644 index 00000000..1170cf99 --- /dev/null +++ b/chartlets.js/src/lib/components/IconButton.tsx @@ -0,0 +1,57 @@ +import { type MouseEvent } from "react"; +import MuiIconButton from "@mui/material/IconButton"; +import MuiIcon from "@mui/material/Icon"; + +import { type ComponentState } from "@/lib/types/state/component"; +import type { ComponentProps } from "@/lib/component/Component"; + +interface IconButtonState extends ComponentState { + icon?: string; + color?: + | "inherit" + | "primary" + | "secondary" + | "success" + | "error" + | "info" + | "warning"; + size?: "small" | "medium" | "large"; +} + +interface IconButtonProps extends ComponentProps, IconButtonState {} + +export function IconButton({ + type, + id, + name, + style, + color, + icon, + size, + disabled, + onChange, +}: IconButtonProps) { + const handleClick = (_event: MouseEvent) => { + if (id) { + onChange({ + componentType: type, + id: id, + property: "clicked", + value: true, + }); + } + }; + return ( + + {icon} + + ); +} diff --git a/chartlets.js/src/lib/components/Typography.tsx b/chartlets.js/src/lib/components/Typography.tsx index 88a65ce5..023adc5b 100644 --- a/chartlets.js/src/lib/components/Typography.tsx +++ b/chartlets.js/src/lib/components/Typography.tsx @@ -1,9 +1,9 @@ import MuiTypography from "@mui/material/Typography"; import { type TypographyVariant } from "@mui/material"; -import { Children } from "@/lib/component/Children"; import type { ComponentState } from "@/lib/types/state/component"; import type { ComponentProps } from "@/lib/component/Component"; +import { Children } from "@/lib/component/Children"; interface TypographyState extends ComponentState { align?: "right" | "left" | "center" | "inherit" | "justify"; diff --git a/chartlets.js/src/lib/index.ts b/chartlets.js/src/lib/index.ts index 087f5955..4fff81d2 100644 --- a/chartlets.js/src/lib/index.ts +++ b/chartlets.js/src/lib/index.ts @@ -35,7 +35,9 @@ export { export { type HostStore } from "@/lib/types/state/options"; ///////////////////////////////////////////////////////////////////// -// Register standard Chartlets components +// Register standard Chartlets components that can be rendered +// by the Chartlets `Component` component. +// Plugins may register their own components. import { registry } from "@/lib/component/Registry"; @@ -43,6 +45,7 @@ import { Box } from "@/lib/components/Box"; import { Button } from "@/lib/components/Button"; import { Checkbox } from "@/lib/components/Checkbox"; import { CircularProgress } from "@/lib/components/CircularProgress"; +import { IconButton } from "@/lib/components/IconButton"; import { Plot } from "@/lib/components/Plot"; import { Select } from "@/lib/components/Select"; import { Typography } from "@/lib/components/Typography"; @@ -51,6 +54,7 @@ registry.register("Box", Box); registry.register("Button", Button); registry.register("Checkbox", Checkbox); registry.register("CircularProgress", CircularProgress); +registry.register("IconButton", IconButton); registry.register("Plot", Plot); registry.register("Select", Select); registry.register("Typography", Typography); diff --git a/chartlets.js/src/lib/types/state/component.ts b/chartlets.js/src/lib/types/state/component.ts index ba600bf4..efe21b82 100644 --- a/chartlets.js/src/lib/types/state/component.ts +++ b/chartlets.js/src/lib/types/state/component.ts @@ -29,6 +29,7 @@ export interface ComponentState { style?: CSSProperties; disabled?: boolean; label?: string; + color?: string; } export interface ContainerState extends ComponentState { diff --git a/chartlets.py/CHANGES.md b/chartlets.py/CHANGES.md index 356767c0..9faea972 100644 --- a/chartlets.py/CHANGES.md +++ b/chartlets.py/CHANGES.md @@ -1,5 +1,7 @@ ## Version 0.0.x (in development) +* Added component `IconButton` and enhanced other components' attributes. + * Channels such as `Input`, `State`, `Output` no longer have a `link` property. Instead, we use a special `id` format, namely `"@app"` and `@container` to address states other than components. diff --git a/chartlets.py/chartlets/components/__init__.py b/chartlets.py/chartlets/components/__init__.py index e6a4e95b..781e2f3f 100644 --- a/chartlets.py/chartlets/components/__init__.py +++ b/chartlets.py/chartlets/components/__init__.py @@ -1,5 +1,6 @@ from .box import Box from .button import Button +from .button import IconButton from .checkbox import Checkbox from .progress import CircularProgress from .progress import CircularProgressWithLabel diff --git a/chartlets.py/chartlets/components/button.py b/chartlets.py/chartlets/components/button.py index 5cb85804..ae4f4d12 100644 --- a/chartlets.py/chartlets/components/button.py +++ b/chartlets.py/chartlets/components/button.py @@ -10,3 +10,44 @@ class Button(Component): text: str | None = None """The button text.""" + + startIcon: str | None = None + """The button's start icon. Must be a name supported by the app's UI.""" + + endIcon: str | None = None + """The button's end icon. Must be a name supported by the app's UI.""" + + color: str | None = None + """The button color. + One of "inherit" | "primary" | "secondary" | "success" | "error" | + "info" | "warning". Defaults to "primary". + """ + + variant: str | None = None + """The button variant. + One "contained" | "outlined" | "text". Defaults to "text". + """ + +@dataclass(frozen=True) +class IconButton(Component): + """Icon buttons are commonly found in app bars and toolbars. + Icons are also appropriate for toggle buttons that allow a + single choice to be selected or deselected, such as adding + or removing a star to an item. + """ + + icon: str | None = None + """The button's icon. Must be a name supported by the app's UI.""" + + color: str | None = None + """The button color. + One of "inherit" | "primary" | "secondary" | "success" | "error" | + "info" | "warning". Defaults to "primary". + """ + + variant: str | None = None + """The button variant. + One "contained" | "outlined" | "text". Defaults to "text". + """ + + diff --git a/chartlets.py/chartlets/version.py b/chartlets.py/chartlets/version.py index b67a45dc..998c172a 100644 --- a/chartlets.py/chartlets/version.py +++ b/chartlets.py/chartlets/version.py @@ -1 +1 @@ -version = "0.0.26" +version = "0.0.27"