From 17952b903b1efc58c5f32642ff36d9939434cc8e Mon Sep 17 00:00:00 2001 From: Abigail Alexander Date: Thu, 6 Feb 2025 11:58:13 +0000 Subject: [PATCH 1/8] Add basic groupbox style --- src/ui/widgets/GroupBox/groupBox.tsx | 96 ++++++++++++++++++---------- 1 file changed, 62 insertions(+), 34 deletions(-) diff --git a/src/ui/widgets/GroupBox/groupBox.tsx b/src/ui/widgets/GroupBox/groupBox.tsx index 878be9db..d173e233 100644 --- a/src/ui/widgets/GroupBox/groupBox.tsx +++ b/src/ui/widgets/GroupBox/groupBox.tsx @@ -8,14 +8,23 @@ import { ChildrenPropOpt, InferWidgetProps, ColorPropOpt, - BoolPropOpt + BoolPropOpt, + FontPropOpt, + IntPropOpt } from "../propTypes"; +import { Font } from "../../../types/font"; +import { Color } from "../../../types/color"; +import Box from "@mui/material/Box"; const GroupBoxProps = { name: StringProp, children: ChildrenPropOpt, backgroundColor: ColorPropOpt, - compat: BoolPropOpt + foregroundColor: ColorPropOpt, + font: FontPropOpt, + compat: BoolPropOpt, + boxStyle: IntPropOpt, + transparent: BoolPropOpt }; // Widget that renders a group-box style border showing the name prop. @@ -24,47 +33,66 @@ const GroupBoxProps = { export const GroupBoxComponent = ( props: InferWidgetProps ): JSX.Element => { - const { compat = false } = props; + const { + compat = false, + backgroundColor = Color.fromRgba(240, 240, 240), + foregroundColor = Color.fromRgba(0, 0, 0), + font = new Font(16), + boxStyle = 0, + transparent = false + } = props; + // Manually render a group-box style border. const innerDivStyle: CSSProperties = { position: "relative", - padding: "16px" + overflow: "visible" + }; + const style: CSSProperties = { + width: "100%", + height: "100%", + padding: "0px", + paddingLeft: "8px", + border: "1px solid black", + whiteSpace: "nowrap", + overflow: "visible", + backgroundColor: transparent ? "transparent" : backgroundColor.toString(), + color: foregroundColor.toString(), + ...font.css() }; + + if (boxStyle === 0) { + // Typical group box with label + } else if (boxStyle === 1) { + // Title bar + + } else if (boxStyle === 2) { + // Border only + + } else { + // None + style.border = "none" + + } // 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"; + innerDivStyle.paddingLeft = "5px"; + innerDivStyle.height = "100%"; + innerDivStyle.width = "100%"; + innerDivStyle.overflow = "visible"; } - // Dimensions match those in the opibuilder groupbox borders. + return ( -
-
- {props.name} -
-
{props.children}
+
+ + {props.name} +
{props.children}
+
+ ); }; From 75abf74ce0de3dcad73651e9f5e62e480be00834 Mon Sep 17 00:00:00 2001 From: Abigail Alexander Date: Mon, 10 Feb 2025 11:33:03 +0000 Subject: [PATCH 2/8] Add groupbox props to widget prop type --- src/ui/widgets/GroupBox/groupBox.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ui/widgets/GroupBox/groupBox.tsx b/src/ui/widgets/GroupBox/groupBox.tsx index d173e233..bbe56ee5 100644 --- a/src/ui/widgets/GroupBox/groupBox.tsx +++ b/src/ui/widgets/GroupBox/groupBox.tsx @@ -98,6 +98,7 @@ export const GroupBoxComponent = ( const GroupBoxWidgetProps = { ...WidgetPropType, + ...GroupBoxProps, name: StringProp, children: ChildrenPropOpt }; From c439adfaa3e1073a35598656d44f80fd89167e51 Mon Sep 17 00:00:00 2001 From: Abigail Alexander Date: Mon, 10 Feb 2025 13:34:48 +0000 Subject: [PATCH 3/8] Update groupbox for different styles --- src/ui/widgets/GroupBox/groupBox.tsx | 78 +++++++++++++++------------- 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/src/ui/widgets/GroupBox/groupBox.tsx b/src/ui/widgets/GroupBox/groupBox.tsx index bbe56ee5..2cb3e7ff 100644 --- a/src/ui/widgets/GroupBox/groupBox.tsx +++ b/src/ui/widgets/GroupBox/groupBox.tsx @@ -16,14 +16,18 @@ 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" +}; + const GroupBoxProps = { name: StringProp, children: ChildrenPropOpt, backgroundColor: ColorPropOpt, foregroundColor: ColorPropOpt, font: FontPropOpt, - compat: BoolPropOpt, - boxStyle: IntPropOpt, + style: IntPropOpt, transparent: BoolPropOpt }; @@ -34,24 +38,25 @@ export const GroupBoxComponent = ( props: InferWidgetProps ): JSX.Element => { const { - compat = false, backgroundColor = Color.fromRgba(240, 240, 240), foregroundColor = Color.fromRgba(0, 0, 0), font = new Font(16), - boxStyle = 0, + style = 0, transparent = false } = props; - // Manually render a group-box style border. - const innerDivStyle: CSSProperties = { - position: "relative", - overflow: "visible" + const outerDivStyle: CSSProperties = { + width: "100%", + height: "100%", + position: "absolute", + padding: "0px", + boxSizing: "border-box" }; - const style: CSSProperties = { + + const boxStyle: CSSProperties = { width: "100%", height: "100%", padding: "0px", - paddingLeft: "8px", border: "1px solid black", whiteSpace: "nowrap", overflow: "visible", @@ -60,39 +65,38 @@ export const GroupBoxComponent = ( ...font.css() }; - if (boxStyle === 0) { + if (style === 0) { // Typical group box with label - } else if (boxStyle === 1) { - // Title bar - - } else if (boxStyle === 2) { - // Border only - - } else { - // None - style.border = "none" - - } - // Specific styling to match the group boxes in opibuilder. - if (compat) { - innerDivStyle.paddingLeft = "5px"; - innerDivStyle.height = "100%"; - innerDivStyle.width = "100%"; - innerDivStyle.overflow = "visible"; + outerDivStyle.padding = "10px"; + outerDivStyle.paddingTop = "0px"; + boxStyle.paddingLeft = "8px"; + } else if (style === 3) { + // No groupbox + boxStyle.border = "none"; } return ( -
- - {props.name} -
{props.children}
+
+ + {style === 1 ? ( +
+ {props.name} +
+ ) : ( + <> + )} + {style === 0 ? {props.name} : <>} +
{props.children}
- ); }; From 66ce71e7a5ef8cceef4aa752403fe5107f25af43 Mon Sep 17 00:00:00 2001 From: Abigail Alexander Date: Mon, 10 Feb 2025 13:35:16 +0000 Subject: [PATCH 4/8] Add groupbox to list of bob widgets and add missing style prop parsing --- src/ui/widgets/EmbeddedDisplay/bobParser.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ui/widgets/EmbeddedDisplay/bobParser.ts b/src/ui/widgets/EmbeddedDisplay/bobParser.ts index 46bc432a..5a740c12 100644 --- a/src/ui/widgets/EmbeddedDisplay/bobParser.ts +++ b/src/ui/widgets/EmbeddedDisplay/bobParser.ts @@ -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", @@ -377,7 +377,8 @@ export function parseBob( initialIndex: ["initial_index", bobParseNumber], showIndex: ["show_index", opiParseBoolean], fallbackSymbol: ["fallback_symbol", opiParseString], - rotation: ["rotation", bobParseNumber] + rotation: ["rotation", bobParseNumber], + style: ["style", bobParseNumber] }; const complexParsers = { From ac69e92a9447d3461a63460de6a13bb78e33a86a Mon Sep 17 00:00:00 2001 From: Abigail Alexander Date: Mon, 10 Feb 2025 13:42:56 +0000 Subject: [PATCH 5/8] Update style prop to styleOpt to ensure no overlap with css style property --- src/ui/widgets/EmbeddedDisplay/bobParser.ts | 2 +- src/ui/widgets/GroupBox/groupBox.tsx | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ui/widgets/EmbeddedDisplay/bobParser.ts b/src/ui/widgets/EmbeddedDisplay/bobParser.ts index 5a740c12..9cb72206 100644 --- a/src/ui/widgets/EmbeddedDisplay/bobParser.ts +++ b/src/ui/widgets/EmbeddedDisplay/bobParser.ts @@ -378,7 +378,7 @@ export function parseBob( showIndex: ["show_index", opiParseBoolean], fallbackSymbol: ["fallback_symbol", opiParseString], rotation: ["rotation", bobParseNumber], - style: ["style", bobParseNumber] + styleOpt: ["style", bobParseNumber] }; const complexParsers = { diff --git a/src/ui/widgets/GroupBox/groupBox.tsx b/src/ui/widgets/GroupBox/groupBox.tsx index 2cb3e7ff..d1acefda 100644 --- a/src/ui/widgets/GroupBox/groupBox.tsx +++ b/src/ui/widgets/GroupBox/groupBox.tsx @@ -27,7 +27,7 @@ const GroupBoxProps = { backgroundColor: ColorPropOpt, foregroundColor: ColorPropOpt, font: FontPropOpt, - style: IntPropOpt, + styleOpt: IntPropOpt, transparent: BoolPropOpt }; @@ -41,7 +41,7 @@ export const GroupBoxComponent = ( backgroundColor = Color.fromRgba(240, 240, 240), foregroundColor = Color.fromRgba(0, 0, 0), font = new Font(16), - style = 0, + styleOpt = 0, transparent = false } = props; @@ -65,12 +65,12 @@ export const GroupBoxComponent = ( ...font.css() }; - if (style === 0) { + if (styleOpt === 0) { // Typical group box with label outerDivStyle.padding = "10px"; outerDivStyle.paddingTop = "0px"; boxStyle.paddingLeft = "8px"; - } else if (style === 3) { + } else if (styleOpt === 3) { // No groupbox boxStyle.border = "none"; } @@ -78,7 +78,7 @@ export const GroupBoxComponent = ( return (
- {style === 1 ? ( + {styleOpt === 1 ? (
)} - {style === 0 ? {props.name} : <>} + {styleOpt === 0 ? {props.name} : <>}
{props.children}
From b35a077c0786c4596e687f351a81508aefaef8e9 Mon Sep 17 00:00:00 2001 From: Abigail Alexander Date: Mon, 10 Feb 2025 13:43:26 +0000 Subject: [PATCH 6/8] Update embeddeddisplay to use new groupbox styleOpt prop --- src/ui/widgets/EmbeddedDisplay/embeddedDisplay.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/widgets/EmbeddedDisplay/embeddedDisplay.tsx b/src/ui/widgets/EmbeddedDisplay/embeddedDisplay.tsx index fcf7b778..66df1954 100644 --- a/src/ui/widgets/EmbeddedDisplay/embeddedDisplay.tsx +++ b/src/ui/widgets/EmbeddedDisplay/embeddedDisplay.tsx @@ -208,7 +208,7 @@ export const EmbeddedDisplay = ( if (props.border?.style === BorderStyle.GroupBox) { return ( - + {component} From f65c28a75fa1ef2141d40b98f5170c9273fd54d5 Mon Sep 17 00:00:00 2001 From: Abigail Alexander Date: Mon, 10 Feb 2025 14:09:06 +0000 Subject: [PATCH 7/8] Update tests and snapshots --- .../__snapshots__/groupBox.test.tsx.snap | 97 +++++++++++++------ src/ui/widgets/GroupBox/groupBox.test.tsx | 37 +++++-- 2 files changed, 96 insertions(+), 38 deletions(-) diff --git a/src/ui/widgets/GroupBox/__snapshots__/groupBox.test.tsx.snap b/src/ui/widgets/GroupBox/__snapshots__/groupBox.test.tsx.snap index f9a7e92e..dc1317a5 100644 --- a/src/ui/widgets/GroupBox/__snapshots__/groupBox.test.tsx.snap +++ b/src/ui/widgets/GroupBox/__snapshots__/groupBox.test.tsx.snap @@ -1,38 +1,73 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[` > it matches the snapshot 1`] = ` -
+exports[` snapshots > it matches the snapshot for Group Box style 1`] = ` +
- Test +
+ + Test + +
+
+
+`; + +exports[` snapshots > it matches the snapshot for Line style 1`] = ` + +
+
+
+
+
+
+`; + +exports[` snapshots > it matches the snapshot for Title Bar style 1`] = ` +
-
+ style="width: 100%; height: 100%; position: absolute; padding: 0px; box-sizing: border-box;" + > +
+
+ Title +
+
+
+
+ +`; + +exports[` snapshots > it matches the snapshot for no style 1`] = ` + +
+
+
+
+
+
`; diff --git a/src/ui/widgets/GroupBox/groupBox.test.tsx b/src/ui/widgets/GroupBox/groupBox.test.tsx index 8a556aa9..db0796ab 100644 --- a/src/ui/widgets/GroupBox/groupBox.test.tsx +++ b/src/ui/widgets/GroupBox/groupBox.test.tsx @@ -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("", (): void => { - test("it matches the snapshot", (): void => { - const snapshot = create( - +describe(" snapshots", (): void => { + test("it matches the snapshot for Group Box style", (): void => { + const { asFragment } = render( + ); - expect(snapshot.toJSON()).toMatchSnapshot(); + expect(asFragment()).toMatchSnapshot(); }); + test("it matches the snapshot for Title Bar style", (): void => { + const { asFragment } = render( + + ); + expect(asFragment()).toMatchSnapshot(); + }); + test("it matches the snapshot for Line style", (): void => { + const { asFragment } = render( + + ); + expect(asFragment()).toMatchSnapshot(); + }); + test("it matches the snapshot for no style", (): void => { + const { asFragment } = render( + + ); + expect(asFragment()).toMatchSnapshot(); + }); +}); +describe("", (): void => { test("it renders the title", (): void => { - const grouping = ; + const grouping = ; const { getByText } = render(grouping); expect(getByText("Test")).toBeInTheDocument(); }); From 55e3ad1d4e8492abb07b875a664efb940a344430 Mon Sep 17 00:00:00 2001 From: Rebecca Williams Date: Mon, 17 Feb 2025 10:22:33 +0000 Subject: [PATCH 8/8] Fix Group widget foreground/title/line colour and missing title name --- src/ui/widgets/EmbeddedDisplay/bobParser.ts | 3 +- .../__snapshots__/groupBox.test.tsx.snap | 16 +++++----- src/ui/widgets/GroupBox/groupBox.tsx | 29 ++++++++++++------- 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/src/ui/widgets/EmbeddedDisplay/bobParser.ts b/src/ui/widgets/EmbeddedDisplay/bobParser.ts index 9cb72206..2677c9fc 100644 --- a/src/ui/widgets/EmbeddedDisplay/bobParser.ts +++ b/src/ui/widgets/EmbeddedDisplay/bobParser.ts @@ -378,7 +378,8 @@ export function parseBob( showIndex: ["show_index", opiParseBoolean], fallbackSymbol: ["fallback_symbol", opiParseString], rotation: ["rotation", bobParseNumber], - styleOpt: ["style", bobParseNumber] + styleOpt: ["style", bobParseNumber], + lineColor: ["line_color", opiParseColor] }; const complexParsers = { diff --git a/src/ui/widgets/GroupBox/__snapshots__/groupBox.test.tsx.snap b/src/ui/widgets/GroupBox/__snapshots__/groupBox.test.tsx.snap index dc1317a5..e45079a5 100644 --- a/src/ui/widgets/GroupBox/__snapshots__/groupBox.test.tsx.snap +++ b/src/ui/widgets/GroupBox/__snapshots__/groupBox.test.tsx.snap @@ -6,13 +6,13 @@ exports[` snapshots > it matches the snapshot for Group Box style="width: 100%; height: 100%; position: absolute; padding: 0px 10px 10px 10px; box-sizing: border-box;" >
Test
@@ -25,10 +25,10 @@ exports[` snapshots > it matches the snapshot for Line styl style="width: 100%; height: 100%; position: absolute; padding: 0px; box-sizing: border-box;" >
@@ -41,15 +41,15 @@ exports[` snapshots > it matches the snapshot for Title Bar style="width: 100%; height: 100%; position: absolute; padding: 0px; box-sizing: border-box;" >
Title
@@ -65,7 +65,7 @@ exports[` snapshots > it matches the snapshot for no style class="MuiBox-root css-m53wvz" >
diff --git a/src/ui/widgets/GroupBox/groupBox.tsx b/src/ui/widgets/GroupBox/groupBox.tsx index d1acefda..431f7e49 100644 --- a/src/ui/widgets/GroupBox/groupBox.tsx +++ b/src/ui/widgets/GroupBox/groupBox.tsx @@ -4,13 +4,13 @@ import { Widget } from "../widget"; import { WidgetPropType } from "../widgetProps"; import { registerWidget } from "../register"; import { - StringProp, ChildrenPropOpt, InferWidgetProps, ColorPropOpt, BoolPropOpt, FontPropOpt, - IntPropOpt + IntPropOpt, + StringPropOpt } from "../propTypes"; import { Font } from "../../../types/font"; import { Color } from "../../../types/color"; @@ -18,14 +18,16 @@ import Box from "@mui/material/Box"; const INNER_DIV_STYLE: CSSProperties = { position: "relative", - overflow: "visible" + overflow: "visible", + color: "black" }; const GroupBoxProps = { - name: StringProp, + name: StringPropOpt, children: ChildrenPropOpt, backgroundColor: ColorPropOpt, foregroundColor: ColorPropOpt, + lineColor: ColorPropOpt, font: FontPropOpt, styleOpt: IntPropOpt, transparent: BoolPropOpt @@ -40,6 +42,7 @@ export const GroupBoxComponent = ( 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 @@ -57,7 +60,7 @@ export const GroupBoxComponent = ( width: "100%", height: "100%", padding: "0px", - border: "1px solid black", + border: "1px solid " + lineColor.toString(), whiteSpace: "nowrap", overflow: "visible", backgroundColor: transparent ? "transparent" : backgroundColor.toString(), @@ -75,6 +78,11 @@ export const GroupBoxComponent = ( boxStyle.border = "none"; } + let name = ""; + if (props.name !== undefined) { + name = props.name; + } + return (
@@ -83,17 +91,18 @@ export const GroupBoxComponent = ( style={{ height: "20px", width: "100%", - backgroundColor: foregroundColor.toString(), + backgroundColor: lineColor.toString(), ...font.css(), - color: backgroundColor.toString() + textAlign: "left", + color: foregroundColor.toString() }} > - {props.name} + {name}
) : ( <> )} - {styleOpt === 0 ? {props.name} : <>} + {styleOpt === 0 ? {name} : <>}
{props.children}
@@ -103,7 +112,7 @@ export const GroupBoxComponent = ( const GroupBoxWidgetProps = { ...WidgetPropType, ...GroupBoxProps, - name: StringProp, + name: StringPropOpt, children: ChildrenPropOpt };