diff --git a/src/ui/widgets/BoolButton/__snapshots__/boolButton.test.tsx.snap b/src/ui/widgets/BoolButton/__snapshots__/boolButton.test.tsx.snap new file mode 100644 index 00000000..a4c0b931 --- /dev/null +++ b/src/ui/widgets/BoolButton/__snapshots__/boolButton.test.tsx.snap @@ -0,0 +1,79 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[` > it renders a button with default values 1`] = ` + + + +`; + +exports[` > it renders a button with led and overwrites default values 1`] = ` + + + +`; + +exports[` > on click change text and led colour 1`] = ` + + + +`; diff --git a/src/ui/widgets/BoolButton/boolButton.test.tsx b/src/ui/widgets/BoolButton/boolButton.test.tsx index b13f446e..86703572 100644 --- a/src/ui/widgets/BoolButton/boolButton.test.tsx +++ b/src/ui/widgets/BoolButton/boolButton.test.tsx @@ -31,14 +31,9 @@ describe("", (): void => { onState: 1, offState: 0 }; - const { getByRole } = render(BoolButtonRenderer(boolButtonProps)); - const button = getByRole("button") as HTMLButtonElement; + const { asFragment } = render(BoolButtonRenderer(boolButtonProps)); - expect(button.textContent).toEqual("On"); - expect(button.style.height).toEqual("30px"); - expect(button.style.width).toEqual("100px"); - expect(button.style.backgroundColor).toEqual("rgb(200, 200, 200)"); - expect(button.style.borderRadius).toEqual(""); + expect(asFragment()).toMatchSnapshot(); }); test("it renders a button with led and overwrites default values", (): void => { @@ -46,17 +41,15 @@ describe("", (): void => { ...TEST_PROPS, showLed: true }; - const { getByRole } = render(BoolButtonRenderer(boolButtonProps)); + const { getByRole, asFragment } = render( + BoolButtonRenderer(boolButtonProps) + ); const button = getByRole("button") as HTMLButtonElement; const spanElement = button.firstChild as HTMLSpanElement; const led = spanElement.children[0] as HTMLSpanElement; const text = spanElement.children[1] as HTMLSpanElement; expect(button.textContent).toEqual("Enabled"); - expect(button.style.height).toEqual("20px"); - expect(button.style.width).toEqual("45px"); - expect(button.style.backgroundColor).toEqual("rgb(20, 20, 200)"); - // Vite adds random hashhex to all CSS module classnames, so check if contains not equals expect(led.className).toContain("Led"); expect(led.style.backgroundColor).toEqual("rgb(0, 235, 10)"); expect(led.style.height).toEqual("11px"); @@ -66,6 +59,7 @@ describe("", (): void => { expect(button.style.borderRadius).toEqual(""); // Vite adds random hashhex to all CSS module classnames, so check if contains not equals expect(text.className).toContain("Text"); + expect(asFragment()).toMatchSnapshot(); }); test("no text if showboolean is false", (): void => { @@ -81,7 +75,6 @@ describe("", (): void => { const text = spanElement.children[1] as HTMLSpanElement; expect(text.textContent).toEqual(""); - expect(button.style.backgroundColor).toEqual("rgb(200, 200, 200)"); }); test("on click change led colour if no text ", async (): Promise => { @@ -110,7 +103,9 @@ describe("", (): void => { ...TEST_PROPS, showLed: true }; - const { getByRole } = render(BoolButtonRenderer(boolButtonProps)); + const { getByRole, asFragment } = render( + BoolButtonRenderer(boolButtonProps) + ); const button = getByRole("button") as HTMLButtonElement; const spanElement = button.firstChild as HTMLSpanElement; const led = spanElement.children[0] as HTMLSpanElement; @@ -124,22 +119,6 @@ describe("", (): void => { expect(text.textContent).toEqual("Disabled"); expect(led.style.backgroundColor).toEqual("rgb(0, 100, 0)"); - }); - - test("change background colour if no LED", async (): Promise => { - const boolButtonProps = { - ...TEST_PROPS, - showLed: false - }; - const { getByRole } = render(BoolButtonRenderer(boolButtonProps)); - const button = getByRole("button") as HTMLButtonElement; - - // Original on values - expect(button.style.backgroundColor).toEqual("rgb(0, 235, 10)"); - - // Click button to off - fireEvent.click(button); - - expect(button.style.backgroundColor).toEqual("rgb(0, 100, 0)"); + expect(asFragment()).toMatchSnapshot(); }); }); diff --git a/src/ui/widgets/BoolButton/boolButton.tsx b/src/ui/widgets/BoolButton/boolButton.tsx index 34d2e271..14adcf8b 100644 --- a/src/ui/widgets/BoolButton/boolButton.tsx +++ b/src/ui/widgets/BoolButton/boolButton.tsx @@ -8,13 +8,16 @@ import { IntPropOpt, PointsPropOpt, BoolPropOpt, - StringPropOpt + StringPropOpt, + FontPropOpt } from "../propTypes"; import { Color } from "../../../types/color"; import classes from "./boolButton.module.css"; import { writePv } from "../../hooks/useSubscription"; import { DType } from "../../../types/dtypes"; import { WIDGET_DEFAULT_SIZES } from "../EmbeddedDisplay/bobParser"; +import { Button as MuiButton, styled } from "@mui/material"; +import { diamondTheme } from "../../../diamondTheme"; // For HTML button, these are the sizes of the buffer on // width and height. Must take into account when allocating @@ -40,9 +43,32 @@ const BoolButtonProps = { showBooleanLabel: BoolPropOpt, showLed: BoolPropOpt, confirmMessage: StringPropOpt, - labelsFromPv: BoolPropOpt + labelsFromPv: BoolPropOpt, + enabled: BoolPropOpt, + font: FontPropOpt }; +const Button = styled(MuiButton)({ + "&.MuiButton-root": { + display: "block", + alignItems: "center", + justifyContent: "center", + height: "100%", + width: "100%", + minWidth: 0, + minHeight: 0, + padding: 0, + overflow: "hidden", + whiteSpace: "nowrap", + wordBreak: "break-word", + textTransform: "none" + }, + "&.Mui-disabled": { + cursor: "not-allowed", + pointerEvents: "all !important" + } +}); + export type BoolButtonComponentProps = InferWidgetProps< typeof BoolButtonProps > & @@ -60,6 +86,8 @@ export const BoolButtonComponent = ( const { width = WIDGET_DEFAULT_SIZES["bool_button"][0], height = WIDGET_DEFAULT_SIZES["bool_button"][1], + foregroundColor = diamondTheme.palette.primary.contrastText, + backgroundColor = diamondTheme.palette.primary.main, pvName, value, onState = 1, @@ -67,13 +95,14 @@ export const BoolButtonComponent = ( onColor = Color.fromRgba(0, 255, 0), offColor = Color.fromRgba(0, 100, 0), squareButton = false, - backgroundColor = Color.fromRgba(200, 200, 200), - foregroundColor = Color.fromRgba(0, 0, 0), showBooleanLabel = true, showLed = true, - labelsFromPv = false + labelsFromPv = false, + enabled = true } = props; + const font = props.font?.css() ?? diamondTheme.typography; + // These could be overwritten by PV labels let { onLabel = "On", offLabel = "Off" } = props; @@ -90,15 +119,6 @@ export const BoolButtonComponent = ( const [ledColor, setLedColor] = useState(offColor.toString()); const doubleValue = value?.getDoubleValue(); - // Establish style - const style: CSSProperties = { - width: width, - height: height, - // If no LED, use on/off colour for button - backgroundColor: showLed ? backgroundColor.toString() : ledColor, - color: foregroundColor.toString() - }; - // Establish LED style const [ledStyle, ledDiameter] = showLed ? createLed(width, height, ledColor) @@ -156,10 +176,16 @@ export const BoolButtonComponent = ( return ( <> - + ); };