From 5596f23172345b02df97cf329f1e5879e607ed45 Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Mon, 31 Mar 2025 08:51:12 +0100 Subject: [PATCH 01/34] Replaced base input with MUI TextField --- src/ui/components/input/input.tsx | 36 +++++---- src/ui/widgets/Input/input.tsx | 124 ++++++++++++++++++------------ 2 files changed, 93 insertions(+), 67 deletions(-) diff --git a/src/ui/components/input/input.tsx b/src/ui/components/input/input.tsx index abbeee07..93d4f9cd 100644 --- a/src/ui/components/input/input.tsx +++ b/src/ui/components/input/input.tsx @@ -1,4 +1,6 @@ +import { TextField, ThemeProvider } from "@mui/material"; import React, { CSSProperties, useState } from "react"; +import { defaultColours } from "../../../colourscheme"; export const InputComponent = (props: { value: string; @@ -17,9 +19,7 @@ export const InputComponent = (props: { event.currentTarget.blur(); } } - function onChange(event: React.ChangeEvent): void { - setInputValue(event.currentTarget.value); - } + function onClick(event: React.MouseEvent): void { /* When focus gained allow editing. */ if (!props.readonly && !editing) { @@ -27,25 +27,27 @@ export const InputComponent = (props: { setEditing(true); } } - function onBlur(event: React.ChangeEvent): void { - setEditing(false); - } if (!editing && inputValue !== props.value) { setInputValue(props.value); } return ( - + + setInputValue(event.target.value)} + onBlur={() => setEditing(false)} + onClick={onClick} + className={props.className} + sx={{ + input: { color: props.style?.color ?? null } + }} + /> + ); }; diff --git a/src/ui/widgets/Input/input.tsx b/src/ui/widgets/Input/input.tsx index d11d2b90..66474aa4 100644 --- a/src/ui/widgets/Input/input.tsx +++ b/src/ui/widgets/Input/input.tsx @@ -1,8 +1,8 @@ -import React from "react"; +import React, { useState } from "react"; import classes from "./input.module.css"; import { writePv } from "../../hooks/useSubscription"; -import { commonCss, Widget } from "../widget"; +import { Widget } from "../widget"; import { PVInputComponent, PVWidgetPropType } from "../widgetProps"; import { registerWidget } from "../register"; import { @@ -16,6 +16,8 @@ import { Font } from "../../../types/font"; import { Color } from "../../../types/color"; import { AlarmQuality, DType } from "../../../types/dtypes"; import { InputComponent } from "../../components/input/input"; +import { TextField, ThemeProvider } from "@mui/material"; +import { defaultColours } from "../../../colourscheme"; export interface InputProps { pvName: string; @@ -34,6 +36,16 @@ export interface InputProps { textAlign?: "left" | "center" | "right"; } +const InputWidgetProps = { + ...PVWidgetPropType, + font: FontPropOpt, + foregroundColor: ColorPropOpt, + backgroundColor: ColorPropOpt, + transparent: BoolPropOpt, + alarmSensitive: BoolPropOpt, + textAlign: ChoicePropOpt(["left", "center", "right"]) +}; + export const SmartInputComponent = ( props: PVInputComponent & { font?: Font; @@ -45,60 +57,72 @@ export const SmartInputComponent = ( } ): JSX.Element => { const alarmQuality = props.value?.getAlarm().quality ?? AlarmQuality.VALID; - let allClasses = classes.Input; - const style = commonCss(props); - if (props.textAlign) { - style.textAlign = props.textAlign; - } - style.color = props.foregroundColor?.toString(); - style.backgroundColor = props.backgroundColor?.toString(); - // Transparent prop overrides backgroundColor. - if (props.transparent) { - style["backgroundColor"] = "transparent"; - } - if (props.readonly) { - allClasses += ` ${classes.readonly}`; - } - if (props.alarmSensitive) { - switch (alarmQuality) { - case AlarmQuality.UNDEFINED: - case AlarmQuality.INVALID: - case AlarmQuality.CHANGING: - style.color = "var(--invalid)"; - break; - case AlarmQuality.WARNING: - style.color = "var(--alarm)"; - break; - case AlarmQuality.ALARM: - style.color = "var(--alarm)"; - break; + // if (props.textAlign) { + // style.textAlign = props.textAlign; + // } + // style.color = props.foregroundColor?.toString(); + // style.backgroundColor = props.backgroundColor?.toString(); + // // Transparent prop overrides backgroundColor. + // if (props.transparent) { + // style["backgroundColor"] = "transparent"; + // } + // if (props.readonly) { + // allClasses += ` ${classes.readonly}`; + // } + // if (props.alarmSensitive) { + // switch (alarmQuality) { + // case AlarmQuality.UNDEFINED: + // case AlarmQuality.INVALID: + // case AlarmQuality.CHANGING: + // style.color = "var(--invalid)"; + // break; + // case AlarmQuality.WARNING: + // style.color = "var(--alarm)"; + // break; + // case AlarmQuality.ALARM: + // style.color = "var(--alarm)"; + // break; + // } + // } + + const [inputValue, setInputValue] = useState(""); + + const onKeyPress = (event: React.KeyboardEvent) => { + if (event.key === "Enter") { + writePv(props.pvName, new DType({ stringValue: inputValue })); + event.currentTarget.blur(); } - } - function onEnter(value: string): void { - writePv(props.pvName, new DType({ stringValue: value })); - } + }; return ( - + + setInputValue(event.target.value)} + sx={{ + "& .MuiInputBase-input": { + color: + props.foregroundColor?.toString() ?? + defaultColours.palette.primary.contrastText, + backgroundColor: props.backgroundColor?.toString() ?? null, + border: "2px solid", + borderRadius: "4px", + borderColor: "#000000" + }, + "& .MuiInputBase-input:hover": { + borderColor: "#0000FF" + }, + "& .MuiInputBase-input:focus": { + borderColor: "#FFFFFF" + } + }} + /> + ); }; -const InputWidgetProps = { - ...PVWidgetPropType, - font: FontPropOpt, - foregroundColor: ColorPropOpt, - backgroundColor: ColorPropOpt, - transparent: BoolPropOpt, - alarmSensitive: BoolPropOpt, - textAlign: ChoicePropOpt(["left", "center", "right"]) -}; - export const Input = ( props: InferWidgetProps ): JSX.Element => ; From ebdb4b87f7b406e72770e3b069e3c30d35fd0084 Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Thu, 3 Apr 2025 16:56:32 +0100 Subject: [PATCH 02/34] Updated theme tokens and changed border colours --- src/ui/components/input/input.tsx | 4 +- src/ui/widgets/Input/input.tsx | 67 ++++++++++++++++++++----------- 2 files changed, 45 insertions(+), 26 deletions(-) diff --git a/src/ui/components/input/input.tsx b/src/ui/components/input/input.tsx index 93d4f9cd..ed8fa3e9 100644 --- a/src/ui/components/input/input.tsx +++ b/src/ui/components/input/input.tsx @@ -1,6 +1,6 @@ import { TextField, ThemeProvider } from "@mui/material"; import React, { CSSProperties, useState } from "react"; -import { defaultColours } from "../../../colourscheme"; +import { diamondTheme } from "../../../diamondTheme"; export const InputComponent = (props: { value: string; @@ -33,7 +33,7 @@ export const InputComponent = (props: { } return ( - + { + const { + enabled = true, + transparent = false, + foregroundColor = diamondTheme.palette.primary.contrastText + } = props; + const alarmQuality = props.value?.getAlarm().quality ?? AlarmQuality.VALID; // if (props.textAlign) { // style.textAlign = props.textAlign; @@ -85,6 +93,11 @@ export const SmartInputComponent = ( // } // } + const font = props.font?.css() ?? diamondTheme.typography; + const backgroundColor = transparent + ? "transparent" + : (props.backgroundColor?.toString() ?? diamondTheme.palette.primary.main); + const [inputValue, setInputValue] = useState(""); const onKeyPress = (event: React.KeyboardEvent) => { @@ -95,31 +108,37 @@ export const SmartInputComponent = ( }; return ( - - setInputValue(event.target.value)} - sx={{ - "& .MuiInputBase-input": { - color: - props.foregroundColor?.toString() ?? - defaultColours.palette.primary.contrastText, - backgroundColor: props.backgroundColor?.toString() ?? null, - border: "2px solid", - borderRadius: "4px", - borderColor: "#000000" - }, - "& .MuiInputBase-input:hover": { + setInputValue(event.target.value)} + sx={{ + "& .MuiInputBase-input": { + fontFamily: font + }, + "&.MuiFormControl-root": { + height: "100%", + width: "100%", + display: "block" + }, + "& .MuiInputBase-root": { + height: "100%", + width: "100%", + padding: 0, + color: foregroundColor.toString(), + backgroundColor: backgroundColor + }, + "& .MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline": + { borderColor: "#0000FF" }, - "& .MuiInputBase-input:focus": { - borderColor: "#FFFFFF" - } - }} - /> - + "& .MuiOutlinedInput-root .MuiOutlinedInput-notchedOutline": { + borderColor: "#00FF00" + } + }} + /> ); }; From 1de8ba7df343a7a6861c532c12b8e56fff663e65 Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Mon, 7 Apr 2025 14:22:19 +0100 Subject: [PATCH 03/34] Move static styling to styled API --- src/ui/widgets/Input/input.tsx | 100 ++++++++++++++++----------------- 1 file changed, 48 insertions(+), 52 deletions(-) diff --git a/src/ui/widgets/Input/input.tsx b/src/ui/widgets/Input/input.tsx index 3933388b..53ccec28 100644 --- a/src/ui/widgets/Input/input.tsx +++ b/src/ui/widgets/Input/input.tsx @@ -1,6 +1,5 @@ import React, { useState } from "react"; -import classes from "./input.module.css"; import { writePv } from "../../hooks/useSubscription"; import { Widget } from "../widget"; import { PVInputComponent, PVWidgetPropType } from "../widgetProps"; @@ -15,8 +14,7 @@ import { import { Font } from "../../../types/font"; import { Color } from "../../../types/color"; import { AlarmQuality, DType } from "../../../types/dtypes"; -import { InputComponent } from "../../components/input/input"; -import { TextField, ThemeProvider } from "@mui/material"; +import { TextField as MuiTextField, styled } from "@mui/material"; import { diamondTheme } from "../../../diamondTheme"; export interface InputProps { @@ -47,6 +45,26 @@ const InputWidgetProps = { textAlign: ChoicePropOpt(["left", "center", "right"]) }; +const TextField = styled(MuiTextField)({ + "&.MuiFormControl-root": { + height: "100%", + width: "100%", + display: "block" + }, + "& .MuiInputBase-root": { + height: "100%", + width: "100%" + }, + "& .MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline": { + border: "2", + borderColor: "#000000" + }, + "&:hover .MuiOutlinedInput-root .MuiOutlinedInput-notchedOutline": { + border: "1", + borderColor: "#000000" + } +}); + export const SmartInputComponent = ( props: PVInputComponent & { font?: Font; @@ -58,42 +76,32 @@ export const SmartInputComponent = ( textAlign?: "left" | "center" | "right"; } ): JSX.Element => { - const { - enabled = true, - transparent = false, - foregroundColor = diamondTheme.palette.primary.contrastText - } = props; + const { enabled = true, transparent = false, textAlign = 0 } = props; + + const font = props.font?.css() ?? diamondTheme.typography; const alarmQuality = props.value?.getAlarm().quality ?? AlarmQuality.VALID; - // if (props.textAlign) { - // style.textAlign = props.textAlign; - // } - // style.color = props.foregroundColor?.toString(); - // style.backgroundColor = props.backgroundColor?.toString(); - // // Transparent prop overrides backgroundColor. - // if (props.transparent) { - // style["backgroundColor"] = "transparent"; - // } - // if (props.readonly) { - // allClasses += ` ${classes.readonly}`; - // } - // if (props.alarmSensitive) { - // switch (alarmQuality) { - // case AlarmQuality.UNDEFINED: - // case AlarmQuality.INVALID: - // case AlarmQuality.CHANGING: - // style.color = "var(--invalid)"; - // break; - // case AlarmQuality.WARNING: - // style.color = "var(--alarm)"; - // break; - // case AlarmQuality.ALARM: - // style.color = "var(--alarm)"; - // break; - // } - // } + const foregroundColor = props.alarmSensitive + ? function () { + switch (alarmQuality) { + case AlarmQuality.UNDEFINED: + case AlarmQuality.INVALID: + case AlarmQuality.CHANGING: + return "var(--invalid)"; + case AlarmQuality.WARNING: + return "var(--alarm)"; + case AlarmQuality.ALARM: + return "var(--alarm)"; + case AlarmQuality.VALID: + return ( + props.foregroundColor?.toString() ?? + diamondTheme.palette.primary.contrastText + ); + } + } + : (props.foregroundColor?.toString() ?? + diamondTheme.palette.primary.contrastText); - const font = props.font?.css() ?? diamondTheme.typography; const backgroundColor = transparent ? "transparent" : (props.backgroundColor?.toString() ?? diamondTheme.palette.primary.main); @@ -116,26 +124,14 @@ export const SmartInputComponent = ( onChange={event => setInputValue(event.target.value)} sx={{ "& .MuiInputBase-input": { + textAlign: "left", + padding: "2px", fontFamily: font }, - "&.MuiFormControl-root": { - height: "100%", - width: "100%", - display: "block" - }, "& .MuiInputBase-root": { - height: "100%", - width: "100%", - padding: 0, - color: foregroundColor.toString(), + alignItems: "start", + color: foregroundColor, backgroundColor: backgroundColor - }, - "& .MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline": - { - borderColor: "#0000FF" - }, - "& .MuiOutlinedInput-root .MuiOutlinedInput-notchedOutline": { - borderColor: "#00FF00" } }} /> From 338fd16f775946fafd33b5fe361449fdb5112892 Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Mon, 7 Apr 2025 14:23:48 +0100 Subject: [PATCH 04/34] Added alignment props to parser --- src/ui/widgets/EmbeddedDisplay/bobParser.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ui/widgets/EmbeddedDisplay/bobParser.ts b/src/ui/widgets/EmbeddedDisplay/bobParser.ts index 4526beb0..9e2fee6a 100644 --- a/src/ui/widgets/EmbeddedDisplay/bobParser.ts +++ b/src/ui/widgets/EmbeddedDisplay/bobParser.ts @@ -380,7 +380,9 @@ export function parseBob( rotation: ["rotation", bobParseNumber], styleOpt: ["style", bobParseNumber], lineColor: ["line_color", opiParseColor], - rotationStep: ["rotation_step", bobParseNumber] + rotationStep: ["rotation_step", bobParseNumber], + horizontalAlignment: ["horizontal_alignment", bobParseNumber], + verticalAlignment: ["vertical_alignment", bobParseNumber] }; const complexParsers = { From 8640e8abdca24fb5857a98e83bf74d2ff9d09673 Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Mon, 7 Apr 2025 14:35:52 +0100 Subject: [PATCH 05/34] Handle alignment props --- src/ui/widgets/Input/input.tsx | 48 ++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/src/ui/widgets/Input/input.tsx b/src/ui/widgets/Input/input.tsx index 53ccec28..e2c41881 100644 --- a/src/ui/widgets/Input/input.tsx +++ b/src/ui/widgets/Input/input.tsx @@ -9,7 +9,8 @@ import { FontPropOpt, ChoicePropOpt, ColorPropOpt, - BoolPropOpt + BoolPropOpt, + FloatPropOpt } from "../propTypes"; import { Font } from "../../../types/font"; import { Color } from "../../../types/color"; @@ -32,6 +33,8 @@ export interface InputProps { onClick: (event: React.MouseEvent) => void; font?: Font; textAlign?: "left" | "center" | "right"; + horizontalAlignment?: number; + verticalAlignment?: number; } const InputWidgetProps = { @@ -42,7 +45,9 @@ const InputWidgetProps = { transparent: BoolPropOpt, alarmSensitive: BoolPropOpt, enabled: BoolPropOpt, - textAlign: ChoicePropOpt(["left", "center", "right"]) + textAlign: ChoicePropOpt(["left", "center", "right"]), + horizontalAlignment: FloatPropOpt, + verticalAlignment: FloatPropOpt }; const TextField = styled(MuiTextField)({ @@ -74,9 +79,16 @@ export const SmartInputComponent = ( alarmSensitive?: boolean; enabled?: boolean; textAlign?: "left" | "center" | "right"; + horizontalAlignment?: number; + verticalAlignment?: number; } ): JSX.Element => { - const { enabled = true, transparent = false, textAlign = 0 } = props; + const { + enabled = true, + transparent = false, + horizontalAlignment = 0, + verticalAlignment = 0 + } = props; const font = props.font?.css() ?? diamondTheme.typography; @@ -106,6 +118,32 @@ export const SmartInputComponent = ( ? "transparent" : (props.backgroundColor?.toString() ?? diamondTheme.palette.primary.main); + const textAlign = function () { + switch (horizontalAlignment) { + case 0: + return "left"; + case 1: + return "center"; + case 2: + return "right"; + default: + return "left"; + } + }; + + const alignItems = function () { + switch (verticalAlignment) { + case 0: + return "start"; + case 1: + return "center"; + case 2: + return "end"; + default: + return "start"; + } + }; + const [inputValue, setInputValue] = useState(""); const onKeyPress = (event: React.KeyboardEvent) => { @@ -124,12 +162,12 @@ export const SmartInputComponent = ( onChange={event => setInputValue(event.target.value)} sx={{ "& .MuiInputBase-input": { - textAlign: "left", + textAlign: textAlign, padding: "2px", fontFamily: font }, "& .MuiInputBase-root": { - alignItems: "start", + alignItems: alignItems, color: foregroundColor, backgroundColor: backgroundColor } From 6d2c24078ab9666824bc25f881cc90ce2a88164a Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Mon, 7 Apr 2025 14:39:32 +0100 Subject: [PATCH 06/34] Updated test and created snapshot --- .../Input/__snapshots__/input.test.tsx.snap | 35 +++++++++++++++++++ src/ui/widgets/Input/input.test.tsx | 7 ++-- 2 files changed, 37 insertions(+), 5 deletions(-) create mode 100644 src/ui/widgets/Input/__snapshots__/input.test.tsx.snap diff --git a/src/ui/widgets/Input/__snapshots__/input.test.tsx.snap b/src/ui/widgets/Input/__snapshots__/input.test.tsx.snap new file mode 100644 index 00000000..4c4154c5 --- /dev/null +++ b/src/ui/widgets/Input/__snapshots__/input.test.tsx.snap @@ -0,0 +1,35 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[` > renders an input 1`] = ` + +
+
+ + +
+
+
+`; diff --git a/src/ui/widgets/Input/input.test.tsx b/src/ui/widgets/Input/input.test.tsx index cd50d4bf..f69a6701 100644 --- a/src/ui/widgets/Input/input.test.tsx +++ b/src/ui/widgets/Input/input.test.tsx @@ -19,10 +19,7 @@ beforeEach((): void => { }); describe("", (): void => { it("renders an input", (): void => { - const { getByDisplayValue } = render(input); - const renderedInput = getByDisplayValue("hello"); - expect(renderedInput).toBeInTheDocument(); - expect(renderedInput).toHaveStyle("color: var(--warning)"); - expect(renderedInput.className).toContain("readonly"); + const { asFragment } = render(input); + expect(asFragment()).toMatchSnapshot(); }); }); From 5159245810193145b3371d1886ad257982b4b6f9 Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Mon, 7 Apr 2025 14:42:01 +0100 Subject: [PATCH 07/34] Removed redundant input component files --- src/ui/components/index.ts | 1 - src/ui/components/input/input.tsx | 53 ------------------------------- 2 files changed, 54 deletions(-) delete mode 100644 src/ui/components/index.ts delete mode 100644 src/ui/components/input/input.tsx diff --git a/src/ui/components/index.ts b/src/ui/components/index.ts deleted file mode 100644 index 46719ea0..00000000 --- a/src/ui/components/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { InputComponent } from "./input/input"; diff --git a/src/ui/components/input/input.tsx b/src/ui/components/input/input.tsx deleted file mode 100644 index ed8fa3e9..00000000 --- a/src/ui/components/input/input.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import { TextField, ThemeProvider } from "@mui/material"; -import React, { CSSProperties, useState } from "react"; -import { diamondTheme } from "../../../diamondTheme"; - -export const InputComponent = (props: { - value: string; - onEnter: (value: string) => void; - readonly?: boolean; - style?: CSSProperties; - className?: string; -}): JSX.Element => { - const [inputValue, setInputValue] = useState(""); - const [editing, setEditing] = useState(false); - function onKeyDown(event: React.KeyboardEvent): void { - if (event.key === "Enter") { - props.onEnter(event.currentTarget.value); - setInputValue(""); - setEditing(false); - event.currentTarget.blur(); - } - } - - function onClick(event: React.MouseEvent): void { - /* When focus gained allow editing. */ - if (!props.readonly && !editing) { - setInputValue(""); - setEditing(true); - } - } - - if (!editing && inputValue !== props.value) { - setInputValue(props.value); - } - - return ( - - setInputValue(event.target.value)} - onBlur={() => setEditing(false)} - onClick={onClick} - className={props.className} - sx={{ - input: { color: props.style?.color ?? null } - }} - /> - - ); -}; From f1060256fec961d9da3f246976a2684614f3fabf Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Mon, 7 Apr 2025 14:45:41 +0100 Subject: [PATCH 08/34] Removed redundant reference to component file --- src/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index a8526f1a..824bc1d4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,6 @@ export * from "./redux"; export * from "./misc"; export * from "./connection"; -export * from "./ui/components"; export * from "./ui/widgets"; export * from "./ui/hooks"; export * from "./types"; From 6572c5c65d7322d4ec49a800127f51f59b3554d9 Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Thu, 10 Apr 2025 13:28:07 +0100 Subject: [PATCH 09/34] Removed redundant horizontalAlignment and verticalAlignment props from parser --- src/ui/widgets/EmbeddedDisplay/bobParser.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/widgets/EmbeddedDisplay/bobParser.ts b/src/ui/widgets/EmbeddedDisplay/bobParser.ts index 9e2fee6a..63cf2c1b 100644 --- a/src/ui/widgets/EmbeddedDisplay/bobParser.ts +++ b/src/ui/widgets/EmbeddedDisplay/bobParser.ts @@ -381,8 +381,8 @@ export function parseBob( styleOpt: ["style", bobParseNumber], lineColor: ["line_color", opiParseColor], rotationStep: ["rotation_step", bobParseNumber], - horizontalAlignment: ["horizontal_alignment", bobParseNumber], - verticalAlignment: ["vertical_alignment", bobParseNumber] + borderWidth: ["border_width", bobParseNumber], + borderColor: ["border_color", opiParseColor] }; const complexParsers = { From eacf481ab7137d828c227cb6dd549235750ad86b Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Thu, 10 Apr 2025 13:36:59 +0100 Subject: [PATCH 10/34] Added textAlignV as ChoicePropOpt and removed unnecessary switch statements --- src/ui/widgets/Input/input.tsx | 44 ++++++---------------------------- 1 file changed, 7 insertions(+), 37 deletions(-) diff --git a/src/ui/widgets/Input/input.tsx b/src/ui/widgets/Input/input.tsx index e2c41881..1fd34bd5 100644 --- a/src/ui/widgets/Input/input.tsx +++ b/src/ui/widgets/Input/input.tsx @@ -9,8 +9,7 @@ import { FontPropOpt, ChoicePropOpt, ColorPropOpt, - BoolPropOpt, - FloatPropOpt + BoolPropOpt } from "../propTypes"; import { Font } from "../../../types/font"; import { Color } from "../../../types/color"; @@ -33,8 +32,7 @@ export interface InputProps { onClick: (event: React.MouseEvent) => void; font?: Font; textAlign?: "left" | "center" | "right"; - horizontalAlignment?: number; - verticalAlignment?: number; + textAlignV?: "top" | "center" | "bottom"; } const InputWidgetProps = { @@ -46,8 +44,7 @@ const InputWidgetProps = { alarmSensitive: BoolPropOpt, enabled: BoolPropOpt, textAlign: ChoicePropOpt(["left", "center", "right"]), - horizontalAlignment: FloatPropOpt, - verticalAlignment: FloatPropOpt + textAlignV: ChoicePropOpt(["top", "center", "bottom"]) }; const TextField = styled(MuiTextField)({ @@ -79,15 +76,14 @@ export const SmartInputComponent = ( alarmSensitive?: boolean; enabled?: boolean; textAlign?: "left" | "center" | "right"; - horizontalAlignment?: number; - verticalAlignment?: number; + textAlignV?: "top" | "center" | "bottom"; } ): JSX.Element => { const { enabled = true, transparent = false, - horizontalAlignment = 0, - verticalAlignment = 0 + textAlign = "left", + textAlignV = "top" } = props; const font = props.font?.css() ?? diamondTheme.typography; @@ -118,32 +114,6 @@ export const SmartInputComponent = ( ? "transparent" : (props.backgroundColor?.toString() ?? diamondTheme.palette.primary.main); - const textAlign = function () { - switch (horizontalAlignment) { - case 0: - return "left"; - case 1: - return "center"; - case 2: - return "right"; - default: - return "left"; - } - }; - - const alignItems = function () { - switch (verticalAlignment) { - case 0: - return "start"; - case 1: - return "center"; - case 2: - return "end"; - default: - return "start"; - } - }; - const [inputValue, setInputValue] = useState(""); const onKeyPress = (event: React.KeyboardEvent) => { @@ -167,7 +137,7 @@ export const SmartInputComponent = ( fontFamily: font }, "& .MuiInputBase-root": { - alignItems: alignItems, + alignItems: textAlignV, color: foregroundColor, backgroundColor: backgroundColor } From 94ebd6f65a4d5220476073ea7f89b098233208cf Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Thu, 10 Apr 2025 14:08:14 +0100 Subject: [PATCH 11/34] Added if-else for vertical alignment --- src/ui/widgets/Input/input.tsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/ui/widgets/Input/input.tsx b/src/ui/widgets/Input/input.tsx index 1fd34bd5..b04f6faf 100644 --- a/src/ui/widgets/Input/input.tsx +++ b/src/ui/widgets/Input/input.tsx @@ -83,7 +83,7 @@ export const SmartInputComponent = ( enabled = true, transparent = false, textAlign = "left", - textAlignV = "top" + textAlignV = "center" } = props; const font = props.font?.css() ?? diamondTheme.typography; @@ -110,6 +110,13 @@ export const SmartInputComponent = ( : (props.foregroundColor?.toString() ?? diamondTheme.palette.primary.contrastText); + let alignmentV = "center"; + if (textAlignV === "top") { + alignmentV = "start"; + } else if (textAlignV === "bottom") { + alignmentV = "end"; + } + const backgroundColor = transparent ? "transparent" : (props.backgroundColor?.toString() ?? diamondTheme.palette.primary.main); @@ -137,7 +144,7 @@ export const SmartInputComponent = ( fontFamily: font }, "& .MuiInputBase-root": { - alignItems: textAlignV, + alignItems: alignmentV, color: foregroundColor, backgroundColor: backgroundColor } From 0fd8d05f19678168b812d4ab6929e98463e0b17e Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Thu, 10 Apr 2025 14:11:23 +0100 Subject: [PATCH 12/34] Changed default background to teal (#80FFFF) --- src/ui/widgets/Input/input.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/widgets/Input/input.tsx b/src/ui/widgets/Input/input.tsx index b04f6faf..657e5c6a 100644 --- a/src/ui/widgets/Input/input.tsx +++ b/src/ui/widgets/Input/input.tsx @@ -119,7 +119,7 @@ export const SmartInputComponent = ( const backgroundColor = transparent ? "transparent" - : (props.backgroundColor?.toString() ?? diamondTheme.palette.primary.main); + : (props.backgroundColor?.toString() ?? "#80FFFF"); const [inputValue, setInputValue] = useState(""); From 5d521d183d47c687ef7fe002f181e290047b255d Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Thu, 10 Apr 2025 14:14:32 +0100 Subject: [PATCH 13/34] Removed redundant border parsing --- src/ui/widgets/EmbeddedDisplay/bobParser.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ui/widgets/EmbeddedDisplay/bobParser.ts b/src/ui/widgets/EmbeddedDisplay/bobParser.ts index 63cf2c1b..4526beb0 100644 --- a/src/ui/widgets/EmbeddedDisplay/bobParser.ts +++ b/src/ui/widgets/EmbeddedDisplay/bobParser.ts @@ -380,9 +380,7 @@ export function parseBob( rotation: ["rotation", bobParseNumber], styleOpt: ["style", bobParseNumber], lineColor: ["line_color", opiParseColor], - rotationStep: ["rotation_step", bobParseNumber], - borderWidth: ["border_width", bobParseNumber], - borderColor: ["border_color", opiParseColor] + rotationStep: ["rotation_step", bobParseNumber] }; const complexParsers = { From f455a353ff650118b37546d8279643d0eada1f2f Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Thu, 10 Apr 2025 14:21:33 +0100 Subject: [PATCH 14/34] Changed color of hover and focussed borders to blue --- src/ui/widgets/Input/input.tsx | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/ui/widgets/Input/input.tsx b/src/ui/widgets/Input/input.tsx index 657e5c6a..1d68f45c 100644 --- a/src/ui/widgets/Input/input.tsx +++ b/src/ui/widgets/Input/input.tsx @@ -9,13 +9,15 @@ import { FontPropOpt, ChoicePropOpt, ColorPropOpt, - BoolPropOpt + BoolPropOpt, + BorderPropOpt } from "../propTypes"; import { Font } from "../../../types/font"; import { Color } from "../../../types/color"; import { AlarmQuality, DType } from "../../../types/dtypes"; import { TextField as MuiTextField, styled } from "@mui/material"; import { diamondTheme } from "../../../diamondTheme"; +import { Border } from "../../../types"; export interface InputProps { pvName: string; @@ -33,6 +35,7 @@ export interface InputProps { font?: Font; textAlign?: "left" | "center" | "right"; textAlignV?: "top" | "center" | "bottom"; + border?: Border; } const InputWidgetProps = { @@ -44,7 +47,8 @@ const InputWidgetProps = { alarmSensitive: BoolPropOpt, enabled: BoolPropOpt, textAlign: ChoicePropOpt(["left", "center", "right"]), - textAlignV: ChoicePropOpt(["top", "center", "bottom"]) + textAlignV: ChoicePropOpt(["top", "center", "bottom"]), + border: BorderPropOpt }; const TextField = styled(MuiTextField)({ @@ -59,11 +63,11 @@ const TextField = styled(MuiTextField)({ }, "& .MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline": { border: "2", - borderColor: "#000000" + borderColor: "#0000FF" }, "&:hover .MuiOutlinedInput-root .MuiOutlinedInput-notchedOutline": { border: "1", - borderColor: "#000000" + borderColor: "#0000FF" } }); @@ -77,6 +81,7 @@ export const SmartInputComponent = ( enabled?: boolean; textAlign?: "left" | "center" | "right"; textAlignV?: "top" | "center" | "bottom"; + border?: Border; } ): JSX.Element => { const { From 88af1b9de0b6be24ada43d8d14cf053fd766171a Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Thu, 10 Apr 2025 14:26:52 +0100 Subject: [PATCH 15/34] Added custom border --- src/ui/widgets/Input/input.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ui/widgets/Input/input.tsx b/src/ui/widgets/Input/input.tsx index 1d68f45c..9ca7f347 100644 --- a/src/ui/widgets/Input/input.tsx +++ b/src/ui/widgets/Input/input.tsx @@ -152,6 +152,10 @@ export const SmartInputComponent = ( alignItems: alignmentV, color: foregroundColor, backgroundColor: backgroundColor + }, + "& .MuiOutlinedInput-root .MuiOutlinedInput-notchedOutline": { + border: props.border?.width, + borderColor: props.border?.color.toString() } }} /> From ecb81aad20f10e3127b2d87ebef22e53d925e373 Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Fri, 11 Apr 2025 10:11:34 +0100 Subject: [PATCH 16/34] Added multiLine to parser --- src/ui/widgets/EmbeddedDisplay/bobParser.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ui/widgets/EmbeddedDisplay/bobParser.ts b/src/ui/widgets/EmbeddedDisplay/bobParser.ts index 4526beb0..83e6c9dc 100644 --- a/src/ui/widgets/EmbeddedDisplay/bobParser.ts +++ b/src/ui/widgets/EmbeddedDisplay/bobParser.ts @@ -380,7 +380,8 @@ export function parseBob( rotation: ["rotation", bobParseNumber], styleOpt: ["style", bobParseNumber], lineColor: ["line_color", opiParseColor], - rotationStep: ["rotation_step", bobParseNumber] + rotationStep: ["rotation_step", bobParseNumber], + multiLine: ["multi_line", opiParseBoolean] }; const complexParsers = { From ec9ae5433ad8a69b02648a073935a4601d75bb5b Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Fri, 11 Apr 2025 10:33:31 +0100 Subject: [PATCH 17/34] Changed default blue border colour --- src/ui/widgets/Input/input.tsx | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/ui/widgets/Input/input.tsx b/src/ui/widgets/Input/input.tsx index 9ca7f347..ace69b45 100644 --- a/src/ui/widgets/Input/input.tsx +++ b/src/ui/widgets/Input/input.tsx @@ -61,13 +61,13 @@ const TextField = styled(MuiTextField)({ height: "100%", width: "100%" }, - "& .MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline": { - border: "2", - borderColor: "#0000FF" - }, - "&:hover .MuiOutlinedInput-root .MuiOutlinedInput-notchedOutline": { - border: "1", - borderColor: "#0000FF" + "& .MuiOutlinedInput-root": { + "&:hover fieldset": { + borderColor: "#1976D2" + }, + "&.Mui-focused fieldset": { + borderColor: "#1976D2" + } } }); @@ -145,7 +145,7 @@ export const SmartInputComponent = ( sx={{ "& .MuiInputBase-input": { textAlign: textAlign, - padding: "2px", + padding: "4px", fontFamily: font }, "& .MuiInputBase-root": { @@ -153,9 +153,9 @@ export const SmartInputComponent = ( color: foregroundColor, backgroundColor: backgroundColor }, - "& .MuiOutlinedInput-root .MuiOutlinedInput-notchedOutline": { - border: props.border?.width, - borderColor: props.border?.color.toString() + "& fieldset": { + border: props.border?.width ?? "0", + borderColor: props.border?.color.toString() ?? "#000000" } }} /> From 02ac24710408788fe5b8284e5080edf8edc38551 Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Fri, 11 Apr 2025 11:34:29 +0100 Subject: [PATCH 18/34] TextField displays existing PV value if available --- src/ui/widgets/Input/input.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ui/widgets/Input/input.tsx b/src/ui/widgets/Input/input.tsx index ace69b45..74b9c49d 100644 --- a/src/ui/widgets/Input/input.tsx +++ b/src/ui/widgets/Input/input.tsx @@ -126,11 +126,14 @@ export const SmartInputComponent = ( ? "transparent" : (props.backgroundColor?.toString() ?? "#80FFFF"); - const [inputValue, setInputValue] = useState(""); + const [inputValue, setInputValue] = useState( + props.value?.getStringValue() ?? "" + ); const onKeyPress = (event: React.KeyboardEvent) => { if (event.key === "Enter") { writePv(props.pvName, new DType({ stringValue: inputValue })); + event.preventDefault(); event.currentTarget.blur(); } }; @@ -138,6 +141,7 @@ export const SmartInputComponent = ( return ( Date: Fri, 11 Apr 2025 13:30:47 +0100 Subject: [PATCH 19/34] Reformatted prop type declaration and disabled cursor when disabled --- src/ui/widgets/Input/input.tsx | 42 ++++++---------------------------- 1 file changed, 7 insertions(+), 35 deletions(-) diff --git a/src/ui/widgets/Input/input.tsx b/src/ui/widgets/Input/input.tsx index 74b9c49d..d45432e6 100644 --- a/src/ui/widgets/Input/input.tsx +++ b/src/ui/widgets/Input/input.tsx @@ -12,31 +12,9 @@ import { BoolPropOpt, BorderPropOpt } from "../propTypes"; -import { Font } from "../../../types/font"; -import { Color } from "../../../types/color"; import { AlarmQuality, DType } from "../../../types/dtypes"; import { TextField as MuiTextField, styled } from "@mui/material"; import { diamondTheme } from "../../../diamondTheme"; -import { Border } from "../../../types"; - -export interface InputProps { - pvName: string; - value: string; - readonly: boolean; - foregroundColor?: Color; - backgroundColor?: Color; - transparent: boolean; - alarm: AlarmQuality; - alarmSensitive: boolean; - onKeyDown: (event: React.KeyboardEvent) => void; - onChange: (event: React.ChangeEvent) => void; - onBlur: (event: React.ChangeEvent) => void; - onClick: (event: React.MouseEvent) => void; - font?: Font; - textAlign?: "left" | "center" | "right"; - textAlignV?: "top" | "center" | "bottom"; - border?: Border; -} const InputWidgetProps = { ...PVWidgetPropType, @@ -67,22 +45,16 @@ const TextField = styled(MuiTextField)({ }, "&.Mui-focused fieldset": { borderColor: "#1976D2" + }, + "&.Mui-disabled": { + cursor: "not-allowed", + pointerEvents: "all !important" } } }); export const SmartInputComponent = ( - props: PVInputComponent & { - font?: Font; - foregroundColor?: Color; - backgroundColor?: Color; - transparent?: boolean; - alarmSensitive?: boolean; - enabled?: boolean; - textAlign?: "left" | "center" | "right"; - textAlignV?: "top" | "center" | "bottom"; - border?: Border; - } + props: PVInputComponent & InferWidgetProps ): JSX.Element => { const { enabled = true, @@ -158,8 +130,8 @@ export const SmartInputComponent = ( backgroundColor: backgroundColor }, "& fieldset": { - border: props.border?.width ?? "0", - borderColor: props.border?.color.toString() ?? "#000000" + border: props.border?.width ?? "1", + borderColor: props.border?.color.toString() ?? "#0000003B" } }} /> From 882d807618baf64ed5153c49ab108ca5ee9aa4a5 Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Fri, 11 Apr 2025 14:51:48 +0100 Subject: [PATCH 20/34] Updated tests, snapshots, and type definitions --- src/ui/widgets/Input/input.test.tsx | 6 ++++-- src/ui/widgets/Input/input.tsx | 2 +- src/ui/widgets/widgetProps.ts | 3 ++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/ui/widgets/Input/input.test.tsx b/src/ui/widgets/Input/input.test.tsx index f69a6701..080fad79 100644 --- a/src/ui/widgets/Input/input.test.tsx +++ b/src/ui/widgets/Input/input.test.tsx @@ -3,13 +3,15 @@ import { SmartInputComponent } from "./input"; import { render } from "@testing-library/react"; import { DAlarm } from "../../../types/dtypes"; import { dstring } from "../../../testResources"; +import { PV, RelativePosition } from "../../../types"; let input: JSX.Element; - +const pv = new PV("loc://test", "ca"); beforeEach((): void => { input = ( ) => { if (event.key === "Enter") { - writePv(props.pvName, new DType({ stringValue: inputValue })); + writePv(props.pvName.name, new DType({ stringValue: inputValue })); event.preventDefault(); event.currentTarget.blur(); } diff --git a/src/ui/widgets/widgetProps.ts b/src/ui/widgets/widgetProps.ts index 90fe66f5..cdc912ef 100644 --- a/src/ui/widgets/widgetProps.ts +++ b/src/ui/widgets/widgetProps.ts @@ -13,6 +13,7 @@ import { import { GenericProp } from "../../types/props"; import { DType } from "../../types/dtypes"; +import { PV } from "../../types"; export const WidgetPropType = { position: PositionProp, @@ -58,4 +59,4 @@ export interface Component { } export type PVComponent = Component & PvState; -export type PVInputComponent = PVComponent & { pvName: string }; +export type PVInputComponent = PVComponent & { pvName: PV }; From 94a836e6754ed3d9ca357bde170a4922975f2908 Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Fri, 11 Apr 2025 14:54:28 +0100 Subject: [PATCH 21/34] Updated slidecontrol test --- src/ui/widgets/SlideControl/slideControl.test.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ui/widgets/SlideControl/slideControl.test.tsx b/src/ui/widgets/SlideControl/slideControl.test.tsx index e6cc4625..88b756a7 100644 --- a/src/ui/widgets/SlideControl/slideControl.test.tsx +++ b/src/ui/widgets/SlideControl/slideControl.test.tsx @@ -2,6 +2,9 @@ import React from "react"; import { render, screen } from "@testing-library/react"; import { ddouble } from "../../../testResources"; import { SlideControlComponent } from "./slideControl"; +import { PV } from "../../../types"; + +const pv = new PV("loc://test", "ca"); test("slideControl", () => { const { container } = render( @@ -9,7 +12,7 @@ test("slideControl", () => { value={ddouble(5)} connected={true} readonly={false} - pvName="dummy" + pvName={pv} max={10} min={0} > From eb34c0b6ed7a72a2e6a17014c2c24e71eb6447a4 Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Fri, 11 Apr 2025 14:56:36 +0100 Subject: [PATCH 22/34] Updated input snapshot --- src/ui/widgets/Input/__snapshots__/input.test.tsx.snap | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/widgets/Input/__snapshots__/input.test.tsx.snap b/src/ui/widgets/Input/__snapshots__/input.test.tsx.snap index 4c4154c5..91ff917c 100644 --- a/src/ui/widgets/Input/__snapshots__/input.test.tsx.snap +++ b/src/ui/widgets/Input/__snapshots__/input.test.tsx.snap @@ -3,7 +3,7 @@ exports[` > renders an input 1`] = `
> renders an input 1`] = ` class="MuiInputBase-input MuiOutlinedInput-input css-16wblaj-MuiInputBase-input-MuiOutlinedInput-input" id=":r0:" type="text" - value="" + value="hello" />