Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions src/ui/widgets/BoolButton/__snapshots__/boolButton.test.tsx.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`<BoolButton /> > it renders a button with default values 1`] = `
<DocumentFragment>
<button
class="MuiButtonBase-root MuiButton-root MuiButton-contained MuiButton-containedPrimary MuiButton-sizeMedium MuiButton-containedSizeMedium MuiButton-colorPrimary MuiButton-root MuiButton-contained MuiButton-containedPrimary MuiButton-sizeMedium MuiButton-containedSizeMedium MuiButton-colorPrimary css-1rvqe9o-MuiButtonBase-root-MuiButton-root"
tabindex="0"
type="button"
>
<span
class="_LedAndText_69ddbc"
style="width: 88px; height: 24px;"
>
<span
class="_Led_69ddbc"
style="width: 16px; height: 16px; background-color: rgb(0, 255, 0); box-shadow: inset 4px 4px 6.4px rgba(255,255,255,.5); visibility: visible;"
/>
<span
class="_Text_69ddbc"
style="max-width: 72px; max-height: 24px;"
>
On
</span>
</span>
</button>
</DocumentFragment>
`;

exports[`<BoolButton /> > it renders a button with led and overwrites default values 1`] = `
<DocumentFragment>
<button
class="MuiButtonBase-root MuiButton-root MuiButton-contained MuiButton-containedPrimary MuiButton-sizeMedium MuiButton-containedSizeMedium MuiButton-colorPrimary MuiButton-root MuiButton-contained MuiButton-containedPrimary MuiButton-sizeMedium MuiButton-containedSizeMedium MuiButton-colorPrimary css-ry8voz-MuiButtonBase-root-MuiButton-root"
tabindex="0"
type="button"
>
<span
class="_LedAndText_69ddbc"
style="width: 33px; height: 14px;"
>
<span
class="_Led_69ddbc"
style="width: 11px; height: 11px; background-color: rgb(0, 235, 10); box-shadow: inset 2.75px 2.75px 4.4px rgba(255,255,255,.5); visibility: visible; border-radius: 0;"
/>
<span
class="_Text_69ddbc"
style="max-width: 22px; max-height: 14px;"
>
Enabled
</span>
</span>
</button>
</DocumentFragment>
`;

exports[`<BoolButton /> > on click change text and led colour 1`] = `
<DocumentFragment>
<button
class="MuiButtonBase-root MuiButton-root MuiButton-contained MuiButton-containedPrimary MuiButton-sizeMedium MuiButton-containedSizeMedium MuiButton-colorPrimary MuiButton-root MuiButton-contained MuiButton-containedPrimary MuiButton-sizeMedium MuiButton-containedSizeMedium MuiButton-colorPrimary css-ry8voz-MuiButtonBase-root-MuiButton-root"
tabindex="0"
type="button"
>
<span
class="_LedAndText_69ddbc"
style="width: 33px; height: 14px;"
>
<span
class="_Led_69ddbc"
style="width: 11px; height: 11px; background-color: rgb(0, 100, 0); box-shadow: inset 2.75px 2.75px 4.4px rgba(255,255,255,.5); visibility: visible; border-radius: 0;"
/>
<span
class="_Text_69ddbc"
style="max-width: 22px; max-height: 14px;"
>
Disabled
</span>
</span>
</button>
</DocumentFragment>
`;
41 changes: 10 additions & 31 deletions src/ui/widgets/BoolButton/boolButton.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,32 +31,25 @@ describe("<BoolButton />", (): 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 => {
const boolButtonProps = {
...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");
Expand All @@ -66,6 +59,7 @@ describe("<BoolButton />", (): 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 => {
Expand All @@ -81,7 +75,6 @@ describe("<BoolButton />", (): 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<void> => {
Expand Down Expand Up @@ -110,7 +103,9 @@ describe("<BoolButton />", (): 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;
Expand All @@ -124,22 +119,6 @@ describe("<BoolButton />", (): void => {

expect(text.textContent).toEqual("Disabled");
expect(led.style.backgroundColor).toEqual("rgb(0, 100, 0)");
});

test("change background colour if no LED", async (): Promise<void> => {
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();
});
});
62 changes: 44 additions & 18 deletions src/ui/widgets/BoolButton/boolButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
> &
Expand All @@ -60,20 +86,23 @@ 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,
offState = 0,
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;

Expand All @@ -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)
Expand Down Expand Up @@ -156,10 +176,16 @@ export const BoolButtonComponent = (

return (
<>
<button
className={classes.BoolButton}
style={style}
<Button
variant="contained"
onClick={handleClick}
disabled={!enabled}
sx={{
fontFamily: font,
color: foregroundColor.toString(),
// If no LED, use on/off colours as background
backgroundColor: showLed ? backgroundColor.toString() : ledColor
}}
>
<span
className={classes.LedAndText}
Expand All @@ -173,7 +199,7 @@ export const BoolButtonComponent = (
{label}
</span>
</span>
</button>
</Button>
</>
);
};
Expand Down