From 478b92cd9317ecafb12c40c6c92af4c93436a1f6 Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Wed, 26 Mar 2025 14:40:55 +0000 Subject: [PATCH 01/13] Replaced base react button group with MUI ToggleButtonGroup --- src/ui/widgets/ChoiceButton/choiceButton.tsx | 107 +++++++++---------- 1 file changed, 53 insertions(+), 54 deletions(-) diff --git a/src/ui/widgets/ChoiceButton/choiceButton.tsx b/src/ui/widgets/ChoiceButton/choiceButton.tsx index ebbc0400..79983f41 100644 --- a/src/ui/widgets/ChoiceButton/choiceButton.tsx +++ b/src/ui/widgets/ChoiceButton/choiceButton.tsx @@ -1,4 +1,4 @@ -import React, { CSSProperties, useEffect, useState } from "react"; +import React, { useEffect, useState } from "react"; import { Widget } from "../widget"; import { PVComponent, PVWidgetPropType } from "../widgetProps"; @@ -13,10 +13,12 @@ import { StringPropOpt } from "../propTypes"; import { DType } from "../../../types/dtypes"; -import classes from "./choiceButton.module.css"; -import { Color } from "../../../types/color"; +// import classes from "./choiceButton.module.css"; import { writePv } from "../../hooks/useSubscription"; import { Font } from "../../../types/font"; +import { ToggleButton, ToggleButtonGroup, ThemeProvider } from "@mui/material"; +import { defaultColours } from "../../../colourscheme"; +import { Color } from "../../../types"; const ChoiceButtonProps = { pvName: StringPropOpt, @@ -50,8 +52,6 @@ export const ChoiceButtonComponent = ( pvName, items = ["Item 1", "Item 2"], horizontal = true, - backgroundColor = Color.fromRgba(210, 210, 210), - foregroundColor = Color.BLACK, selectedColor = Color.fromRgba(200, 200, 200), font = new Font(14) } = props; @@ -74,61 +74,60 @@ export const ChoiceButtonComponent = ( // Number of buttons to create const numButtons = options.length || 1; // Determine width and height of buttons if horizontal or vertically placed - const buttonHeight = horizontal ? height : height / numButtons - 4; - const buttonWidth = horizontal ? width / numButtons - 4 : width; + const buttonHeight = horizontal ? height : height / numButtons; + const buttonWidth = horizontal ? width / numButtons : width; - const style: CSSProperties = { - height: buttonHeight, - width: buttonWidth, - textAlignLast: "center", - cursor: enabled ? "default" : "not-allowed", - color: foregroundColor?.toString(), - ...font.css() - }; - - function handleClick(index: number) { + const handleChange = ( + event: React.MouseEvent, + newSelect: number + ) => { // Write to PV if (pvName) { - writePv(pvName, new DType({ doubleValue: index })); + writePv(pvName, new DType({ doubleValue: newSelect })); } - } - - // Iterate over items to create buttons - const elements: Array = []; - options.forEach((item: string | null | undefined, idx: number) => { - if (typeof item === "string") { - elements.push( - - ); - } - }); + setSelected(newSelect); + }; return ( -
- {elements} -
+ + + {options + .filter(item => typeof item === "string") + .map((item, idx) => ( + + {item} + + ))} + + ); }; From 0d2f1d6382bea89c6c45393f96fed07b1ab3ba4a Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Wed, 26 Mar 2025 15:33:12 +0000 Subject: [PATCH 02/13] Commented out expect statements checking the styling --- .../ChoiceButton/choiceButton.test.tsx | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/ui/widgets/ChoiceButton/choiceButton.test.tsx b/src/ui/widgets/ChoiceButton/choiceButton.test.tsx index ed3e634c..8f5925ff 100644 --- a/src/ui/widgets/ChoiceButton/choiceButton.test.tsx +++ b/src/ui/widgets/ChoiceButton/choiceButton.test.tsx @@ -18,10 +18,10 @@ describe("", (): void => { expect(buttons[0].textContent).toEqual("Item 1"); expect(buttons[1].textContent).toEqual("Item 2"); - expect(buttons[0].style.height).toEqual("43px"); - expect(buttons[1].style.width).toEqual("46px"); - expect(buttons[0].style.backgroundColor).toEqual("rgb(210, 210, 210)"); - expect(buttons[1].style.fontSize).toEqual("0.875rem"); + // expect(buttons[0].style.height).toEqual("43px"); + // expect(buttons[1].style.width).toEqual("46px"); + // expect(buttons[0].style.backgroundColor).toEqual("rgb(210, 210, 210)"); + // expect(buttons[1].style.fontSize).toEqual("0.875rem"); }); test("pass props to widget", (): void => { @@ -41,14 +41,15 @@ describe("", (): void => { expect(buttons.length).toEqual(4); // First button is selected therefore different color and box shadow - expect(buttons[0].style.boxShadow).toEqual( - "inset 0px 23px 35px 0px rgba(0,0,0,0.3)" - ); - expect(buttons[0].style.backgroundColor).toEqual("rgb(10, 60, 40)"); + // expect(buttons[0].style.boxShadow).toEqual( + // "inset 0px 23px 35px 0px rgba(0,0,0,0.3)" + // ); + // expect(buttons[0].style.backgroundColor).toEqual("rgb(10, 60, 40)"); expect(buttons[2].textContent).toEqual("Setting"); - expect(buttons[3].style.cursor).toEqual("not-allowed"); - expect(buttons[3].style.height).toEqual("31px"); - expect(buttons[3].style.backgroundColor).toEqual("rgb(20, 20, 200)"); + expect(buttons[3]).toHaveProperty("disabled", true); + // expect(buttons[3].style.cursor).toEqual("not-allowed"); + // expect(buttons[3].style.height).toEqual("31px"); + // expect(buttons[3].style.backgroundColor).toEqual("rgb(20, 20, 200)"); }); test("pass props to widget, using itemsFromPv", (): void => { From 851d122a05de5989f58ee65f8d0e6596d3ff205d Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Mon, 7 Apr 2025 09:54:01 +0100 Subject: [PATCH 03/13] Removed ThemeProvider --- src/ui/widgets/ChoiceButton/choiceButton.tsx | 78 ++++++++++---------- 1 file changed, 38 insertions(+), 40 deletions(-) diff --git a/src/ui/widgets/ChoiceButton/choiceButton.tsx b/src/ui/widgets/ChoiceButton/choiceButton.tsx index 79983f41..b11d4cd2 100644 --- a/src/ui/widgets/ChoiceButton/choiceButton.tsx +++ b/src/ui/widgets/ChoiceButton/choiceButton.tsx @@ -17,7 +17,7 @@ import { DType } from "../../../types/dtypes"; import { writePv } from "../../hooks/useSubscription"; import { Font } from "../../../types/font"; import { ToggleButton, ToggleButtonGroup, ThemeProvider } from "@mui/material"; -import { defaultColours } from "../../../colourscheme"; +import { diamondTheme } from "../../../diamondTheme"; import { Color } from "../../../types"; const ChoiceButtonProps = { @@ -89,45 +89,43 @@ export const ChoiceButtonComponent = ( }; return ( - - - {options - .filter(item => typeof item === "string") - .map((item, idx) => ( - - {item} - - ))} - - + + {options + .filter(item => typeof item === "string") + .map((item, idx) => ( + + {item} + + ))} + ); }; From 048e1887b07b45c57dac0629ab59f79841462e87 Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Mon, 7 Apr 2025 10:53:05 +0100 Subject: [PATCH 04/13] Moved static styling to styled API --- src/ui/widgets/ChoiceButton/choiceButton.tsx | 38 +++++++++++++------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/ui/widgets/ChoiceButton/choiceButton.tsx b/src/ui/widgets/ChoiceButton/choiceButton.tsx index b11d4cd2..efcafe1f 100644 --- a/src/ui/widgets/ChoiceButton/choiceButton.tsx +++ b/src/ui/widgets/ChoiceButton/choiceButton.tsx @@ -15,8 +15,11 @@ import { import { DType } from "../../../types/dtypes"; // import classes from "./choiceButton.module.css"; import { writePv } from "../../hooks/useSubscription"; -import { Font } from "../../../types/font"; -import { ToggleButton, ToggleButtonGroup, ThemeProvider } from "@mui/material"; +import { + ToggleButton as MuiToggleButton, + styled, + ToggleButtonGroup +} from "@mui/material"; import { diamondTheme } from "../../../diamondTheme"; import { Color } from "../../../types"; @@ -40,6 +43,19 @@ export type ChoiceButtonComponentProps = InferWidgetProps< > & PVComponent; +const ToggleButton = styled(MuiToggleButton)({ + "&.MuiToggleButton-root": { + textTransform: "none", + overflow: "hidden", + padding: 0, + lineHeight: 1 + }, + "&.Mui-disabled": { + cursor: "not-allowed", + pointerEvents: "all !important" + } +}); + export const ChoiceButtonComponent = ( props: ChoiceButtonComponentProps ): JSX.Element => { @@ -52,9 +68,11 @@ export const ChoiceButtonComponent = ( pvName, items = ["Item 1", "Item 2"], horizontal = true, - selectedColor = Color.fromRgba(200, 200, 200), - font = new Font(14) + foregroundColor = diamondTheme.palette.primary.contrastText, + backgroundColor = diamondTheme.palette.primary.main, + selectedColor = Color.fromRgba(200, 200, 200) } = props; + const font = props.font?.css() ?? diamondTheme.typography; const [selected, setSelected] = useState(value?.getDoubleValue()); // Use items from file, unless itemsFRomPv set @@ -92,7 +110,7 @@ export const ChoiceButtonComponent = ( Date: Mon, 7 Apr 2025 10:57:29 +0100 Subject: [PATCH 05/13] Updated tests --- .../__snapshots__/choiceButton.test.tsx.snap | 79 +++++++++++++++++++ .../ChoiceButton/choiceButton.test.tsx | 22 ++---- 2 files changed, 87 insertions(+), 14 deletions(-) create mode 100644 src/ui/widgets/ChoiceButton/__snapshots__/choiceButton.test.tsx.snap diff --git a/src/ui/widgets/ChoiceButton/__snapshots__/choiceButton.test.tsx.snap b/src/ui/widgets/ChoiceButton/__snapshots__/choiceButton.test.tsx.snap new file mode 100644 index 00000000..80358f68 --- /dev/null +++ b/src/ui/widgets/ChoiceButton/__snapshots__/choiceButton.test.tsx.snap @@ -0,0 +1,79 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[` > it renders ChoiceButton with default props 1`] = ` + +
+ + +
+
+`; + +exports[` > pass props to widget 1`] = ` + +
+ + + + +
+
+`; diff --git a/src/ui/widgets/ChoiceButton/choiceButton.test.tsx b/src/ui/widgets/ChoiceButton/choiceButton.test.tsx index 8f5925ff..745a67a5 100644 --- a/src/ui/widgets/ChoiceButton/choiceButton.test.tsx +++ b/src/ui/widgets/ChoiceButton/choiceButton.test.tsx @@ -13,15 +13,14 @@ describe("", (): void => { const choiceButtonProps = { value: null }; - const { getAllByRole } = render(ChoiceButtonRenderer(choiceButtonProps)); + const { getAllByRole, asFragment } = render( + ChoiceButtonRenderer(choiceButtonProps) + ); const buttons = getAllByRole("button") as Array; expect(buttons[0].textContent).toEqual("Item 1"); expect(buttons[1].textContent).toEqual("Item 2"); - // expect(buttons[0].style.height).toEqual("43px"); - // expect(buttons[1].style.width).toEqual("46px"); - // expect(buttons[0].style.backgroundColor).toEqual("rgb(210, 210, 210)"); - // expect(buttons[1].style.fontSize).toEqual("0.875rem"); + expect(asFragment()).toMatchSnapshot(); }); test("pass props to widget", (): void => { @@ -36,20 +35,15 @@ describe("", (): void => { itemsFromPv: false, enabled: false }; - const { getAllByRole } = render(ChoiceButtonRenderer(choiceButtonProps)); + const { getAllByRole, asFragment } = render( + ChoiceButtonRenderer(choiceButtonProps) + ); const buttons = getAllByRole("button") as Array; expect(buttons.length).toEqual(4); - // First button is selected therefore different color and box shadow - // expect(buttons[0].style.boxShadow).toEqual( - // "inset 0px 23px 35px 0px rgba(0,0,0,0.3)" - // ); - // expect(buttons[0].style.backgroundColor).toEqual("rgb(10, 60, 40)"); expect(buttons[2].textContent).toEqual("Setting"); expect(buttons[3]).toHaveProperty("disabled", true); - // expect(buttons[3].style.cursor).toEqual("not-allowed"); - // expect(buttons[3].style.height).toEqual("31px"); - // expect(buttons[3].style.backgroundColor).toEqual("rgb(20, 20, 200)"); + expect(asFragment()).toMatchSnapshot(); }); test("pass props to widget, using itemsFromPv", (): void => { From 30f17a7f5b0258cc1e1451af6dbb4c3582f56ef8 Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Wed, 9 Apr 2025 16:58:14 +0100 Subject: [PATCH 06/13] Removed redundant height and width for ButtonGroup --- src/ui/widgets/ChoiceButton/choiceButton.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/ui/widgets/ChoiceButton/choiceButton.tsx b/src/ui/widgets/ChoiceButton/choiceButton.tsx index efcafe1f..838398d8 100644 --- a/src/ui/widgets/ChoiceButton/choiceButton.tsx +++ b/src/ui/widgets/ChoiceButton/choiceButton.tsx @@ -114,10 +114,6 @@ export const ChoiceButtonComponent = ( value={selected} onChange={handleChange} orientation={horizontal ? "horizontal" : "vertical"} - sx={{ - height: height, - width: width - }} > {options .filter(item => typeof item === "string") From 7c44cc8956281da68147caa30aace81432c3bff1 Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Thu, 10 Apr 2025 08:42:04 +0100 Subject: [PATCH 07/13] Set opacity to 0.6 for hover and selected-hover --- src/ui/widgets/ChoiceButton/choiceButton.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ui/widgets/ChoiceButton/choiceButton.tsx b/src/ui/widgets/ChoiceButton/choiceButton.tsx index 838398d8..aa398175 100644 --- a/src/ui/widgets/ChoiceButton/choiceButton.tsx +++ b/src/ui/widgets/ChoiceButton/choiceButton.tsx @@ -127,8 +127,12 @@ export const ChoiceButtonComponent = ( fontFamily: font, color: foregroundColor.toString(), backgroundColor: backgroundColor.toString(), - "&.Mui-selected, &.Mui-selected:hover, &:hover": { + "&.Mui-selected": { backgroundColor: selectedColor.toString() + }, + "&.Mui-selected:hover, &:hover": { + backgroundColor: selectedColor.toString(), + opacity: 0.6 } }} > From 9e799c19d294d7604464f92ed6661da52757ad46 Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Thu, 10 Apr 2025 09:38:27 +0100 Subject: [PATCH 08/13] Added borders to buttons and fixed text wrapping --- src/ui/widgets/ChoiceButton/choiceButton.tsx | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/ui/widgets/ChoiceButton/choiceButton.tsx b/src/ui/widgets/ChoiceButton/choiceButton.tsx index aa398175..bf331faa 100644 --- a/src/ui/widgets/ChoiceButton/choiceButton.tsx +++ b/src/ui/widgets/ChoiceButton/choiceButton.tsx @@ -47,12 +47,21 @@ const ToggleButton = styled(MuiToggleButton)({ "&.MuiToggleButton-root": { textTransform: "none", overflow: "hidden", + display: "block", padding: 0, - lineHeight: 1 + lineHeight: 1, + alignItems: "center", + justifyContent: "center", + textOverflow: "ellipsis", + wordWrap: "break-word" }, "&.Mui-disabled": { cursor: "not-allowed", pointerEvents: "all !important" + }, + "&.MuiToggleButtonGroup-grouped": { + border: "1px solid !important", + borderColor: "#000000" } }); @@ -114,6 +123,11 @@ export const ChoiceButtonComponent = ( value={selected} onChange={handleChange} orientation={horizontal ? "horizontal" : "vertical"} + sx={{ + display: "flex", + height: "100%", + width: "100%" + }} > {options .filter(item => typeof item === "string") @@ -122,8 +136,8 @@ export const ChoiceButtonComponent = ( key={item} value={idx} sx={{ - minWidth: buttonWidth, - minHeight: buttonHeight, + maxWidth: buttonWidth, + maxHeight: buttonHeight, fontFamily: font, color: foregroundColor.toString(), backgroundColor: backgroundColor.toString(), From 73f6b7d41a580137fba1ee8331463816ed193a7b Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Thu, 10 Apr 2025 09:42:01 +0100 Subject: [PATCH 09/13] Updated snapshots --- .../__snapshots__/choiceButton.test.tsx.snap | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/ui/widgets/ChoiceButton/__snapshots__/choiceButton.test.tsx.snap b/src/ui/widgets/ChoiceButton/__snapshots__/choiceButton.test.tsx.snap index 80358f68..c2d83256 100644 --- a/src/ui/widgets/ChoiceButton/__snapshots__/choiceButton.test.tsx.snap +++ b/src/ui/widgets/ChoiceButton/__snapshots__/choiceButton.test.tsx.snap @@ -3,12 +3,12 @@ exports[` > it renders ChoiceButton with default props 1`] = `