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
6 changes: 4 additions & 2 deletions src/ui/widgets/EmbeddedDisplay/bobParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const BOB_WIDGET_MAPPING: { [key: string]: any } = {
display: "display",
ellipse: "ellipse",
embedded: "embeddedDisplay",
group: "groupingcontainer",
group: "groupbox",
label: "label",
led: "led",
textupdate: "readback",
Expand Down Expand Up @@ -377,7 +377,9 @@ export function parseBob(
initialIndex: ["initial_index", bobParseNumber],
showIndex: ["show_index", opiParseBoolean],
fallbackSymbol: ["fallback_symbol", opiParseString],
rotation: ["rotation", bobParseNumber]
rotation: ["rotation", bobParseNumber],
styleOpt: ["style", bobParseNumber],
lineColor: ["line_color", opiParseColor]
};

const complexParsers = {
Expand Down
2 changes: 1 addition & 1 deletion src/ui/widgets/EmbeddedDisplay/embeddedDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ export const EmbeddedDisplay = (
if (props.border?.style === BorderStyle.GroupBox) {
return (
<MacroContext.Provider value={embeddedDisplayMacroContext}>
<GroupBoxComponent name={resolvedName} compat={true}>
<GroupBoxComponent name={resolvedName} styleOpt={0}>
{component}
</GroupBoxComponent>
</MacroContext.Provider>
Expand Down
97 changes: 66 additions & 31 deletions src/ui/widgets/GroupBox/__snapshots__/groupBox.test.tsx.snap
Original file line number Diff line number Diff line change
@@ -1,38 +1,73 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`<GroupingContainerComponent /> > it matches the snapshot 1`] = `
<div
style={
{
"backgroundColor": "transparent",
"height": "100%",
"outline": "1px dotted black",
"outlineOffset": "-7px",
"width": "100%",
}
}
>
exports[`<GroupBoxComponent /> snapshots > it matches the snapshot for Group Box style 1`] = `
<DocumentFragment>
<div
style={
{
"backgroundColor": "rgba(255,255,255,255)",
"fontSize": "13px",
"left": "20px",
"padding": "0 2px 0 2px",
"position": "absolute",
"top": "0",
}
}
style="width: 100%; height: 100%; position: absolute; padding: 0px 10px 10px 10px; box-sizing: border-box;"
>
Test
<fieldset
class="MuiBox-root css-1ho00z6"
>
<legend>
Test
</legend>
<div
style="position: relative; overflow: visible; color: black;"
/>
</fieldset>
</div>
</DocumentFragment>
`;

exports[`<GroupBoxComponent /> snapshots > it matches the snapshot for Line style 1`] = `
<DocumentFragment>
<div
style="width: 100%; height: 100%; position: absolute; padding: 0px; box-sizing: border-box;"
>
<fieldset
class="MuiBox-root css-1wd2nmm"
>
<div
style="position: relative; overflow: visible; color: black;"
/>
</fieldset>
</div>
</DocumentFragment>
`;

exports[`<GroupBoxComponent /> snapshots > it matches the snapshot for Title Bar style 1`] = `
<DocumentFragment>
<div
style={
{
"padding": "16px",
"position": "relative",
}
}
/>
</div>
style="width: 100%; height: 100%; position: absolute; padding: 0px; box-sizing: border-box;"
>
<fieldset
class="MuiBox-root css-1wd2nmm"
>
<div
style="height: 20px; width: 100%; background-color: rgb(0, 0, 0); font-family: Liberation sans,sans-serif; font-weight: normal; font-style: normal; font-size: 1rem; text-align: left; color: rgb(0, 0, 0);"
>
Title
</div>
<div
style="position: relative; overflow: visible; color: black;"
/>
</fieldset>
</div>
</DocumentFragment>
`;

exports[`<GroupBoxComponent /> snapshots > it matches the snapshot for no style 1`] = `
<DocumentFragment>
<div
style="width: 100%; height: 100%; position: absolute; padding: 0px; box-sizing: border-box;"
>
<fieldset
class="MuiBox-root css-m53wvz"
>
<div
style="position: relative; overflow: visible; color: black;"
/>
</fieldset>
</div>
</DocumentFragment>
`;
37 changes: 30 additions & 7 deletions src/ui/widgets/GroupBox/groupBox.test.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,42 @@
import React from "react";
import { GroupBoxComponent } from "./groupBox";
import { create } from "react-test-renderer";
import { Color } from "../../../types/color";
import { render } from "@testing-library/react";

describe("<GroupingContainerComponent />", (): void => {
test("it matches the snapshot", (): void => {
const snapshot = create(
<GroupBoxComponent name={"Test"} backgroundColor={Color.WHITE} />
describe("<GroupBoxComponent /> snapshots", (): void => {
test("it matches the snapshot for Group Box style", (): void => {
const { asFragment } = render(
<GroupBoxComponent
name={"Test"}
backgroundColor={Color.WHITE}
styleOpt={0}
/>
);
expect(snapshot.toJSON()).toMatchSnapshot();
expect(asFragment()).toMatchSnapshot();
});
test("it matches the snapshot for Title Bar style", (): void => {
const { asFragment } = render(
<GroupBoxComponent name={"Title"} styleOpt={1} />
);
expect(asFragment()).toMatchSnapshot();
});
test("it matches the snapshot for Line style", (): void => {
const { asFragment } = render(
<GroupBoxComponent name={"No Title"} styleOpt={2} />
);
expect(asFragment()).toMatchSnapshot();
});
test("it matches the snapshot for no style", (): void => {
const { asFragment } = render(
<GroupBoxComponent name={"None"} styleOpt={3} />
);
expect(asFragment()).toMatchSnapshot();
});
});

describe("<GroupBoxComponent />", (): void => {
test("it renders the title", (): void => {
const grouping = <GroupBoxComponent name={"Test"} />;
const grouping = <GroupBoxComponent name={"Test"} styleOpt={1} />;
const { getByText } = render(grouping);
expect(getByText("Test")).toBeInTheDocument();
});
Expand Down
126 changes: 84 additions & 42 deletions src/ui/widgets/GroupBox/groupBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,33 @@ import { Widget } from "../widget";
import { WidgetPropType } from "../widgetProps";
import { registerWidget } from "../register";
import {
StringProp,
ChildrenPropOpt,
InferWidgetProps,
ColorPropOpt,
BoolPropOpt
BoolPropOpt,
FontPropOpt,
IntPropOpt,
StringPropOpt
} from "../propTypes";
import { Font } from "../../../types/font";
import { Color } from "../../../types/color";
import Box from "@mui/material/Box";

const INNER_DIV_STYLE: CSSProperties = {
position: "relative",
overflow: "visible",
color: "black"
};

const GroupBoxProps = {
name: StringProp,
name: StringPropOpt,
children: ChildrenPropOpt,
backgroundColor: ColorPropOpt,
compat: BoolPropOpt
foregroundColor: ColorPropOpt,
lineColor: ColorPropOpt,
font: FontPropOpt,
styleOpt: IntPropOpt,
transparent: BoolPropOpt
};

// Widget that renders a group-box style border showing the name prop.
Expand All @@ -24,53 +39,80 @@ const GroupBoxProps = {
export const GroupBoxComponent = (
props: InferWidgetProps<typeof GroupBoxProps>
): JSX.Element => {
const { compat = false } = props;
// Manually render a group-box style border.
const innerDivStyle: CSSProperties = {
position: "relative",
padding: "16px"
const {
backgroundColor = Color.fromRgba(240, 240, 240),
foregroundColor = Color.fromRgba(0, 0, 0),
lineColor = Color.fromRgba(0, 0, 0),
font = new Font(16),
styleOpt = 0,
transparent = false
} = props;

const outerDivStyle: CSSProperties = {
width: "100%",
height: "100%",
position: "absolute",
padding: "0px",
boxSizing: "border-box"
};

const boxStyle: CSSProperties = {
width: "100%",
height: "100%",
padding: "0px",
border: "1px solid " + lineColor.toString(),
whiteSpace: "nowrap",
overflow: "visible",
backgroundColor: transparent ? "transparent" : backgroundColor.toString(),
color: foregroundColor.toString(),
...font.css()
};
// Specific styling to match the group boxes in opibuilder.
if (compat) {
innerDivStyle.padding = undefined;
innerDivStyle.top = "16px";
innerDivStyle.left = "16px";
innerDivStyle.height = "calc(100% - 32px)";
innerDivStyle.width = "calc(100% - 32px)";
innerDivStyle.overflow = "hidden";

if (styleOpt === 0) {
// Typical group box with label
outerDivStyle.padding = "10px";
outerDivStyle.paddingTop = "0px";
boxStyle.paddingLeft = "8px";
} else if (styleOpt === 3) {
// No groupbox
boxStyle.border = "none";
}

let name = "";
if (props.name !== undefined) {
name = props.name;
}
// Dimensions match those in the opibuilder groupbox borders.

return (
<div
style={{
width: "100%",
height: "100%",
outline: "1px dotted black",
outlineOffset: "-7px",
backgroundColor: "transparent"
}}
>
<div
style={{
position: "absolute",
top: "0",
left: "20px",
fontSize: "13px",
padding: "0 2px 0 2px",
backgroundColor:
props.backgroundColor?.toString() ?? "rgb(200,200,200)"
}}
>
{props.name}
</div>
<div style={innerDivStyle}>{props.children}</div>
<div style={outerDivStyle}>
<Box component="fieldset" sx={boxStyle}>
{styleOpt === 1 ? (
<div
style={{
height: "20px",
width: "100%",
backgroundColor: lineColor.toString(),
...font.css(),
textAlign: "left",
color: foregroundColor.toString()
}}
>
{name}
</div>
) : (
<></>
)}
{styleOpt === 0 ? <legend>{name}</legend> : <></>}
<div style={INNER_DIV_STYLE}>{props.children}</div>
</Box>
</div>
);
};

const GroupBoxWidgetProps = {
...WidgetPropType,
name: StringProp,
...GroupBoxProps,
name: StringPropOpt,
children: ChildrenPropOpt
};

Expand Down