Skip to content

Commit ef8b90b

Browse files
authored
84 replace action button with mui button (#85)
* Replaced default html button with MUI Button * Added border and disabled settings * Updated file for prettier * Prettier again * Prettier still * Final time * Refactored code to be compatible with tests * Updated test snapshot * Fixed error in snapshot * Corrected the default grey colour * Corrected the default text colour * Added settings to change cursor when button is disabled * Tidied the colour prop declarations * Fixed text wrapping * Addedd transparent to parser test * Renamed colourscheme file and defaultColours name * Moved decision making out of the Button declaration and reorganised styling parameters * Moved ThemeProvider to embeddedDisplay * Updated the snapshot * Changed it so that button variant is "text" when transparent, otherwise it's "contained" * Added rotationStep to bobParser * Moved static styling components to use styled API * Set lineHeight to 1 * Updated snapshot * Fixed text rotation in Button * Updated snapshot
1 parent 6e57a14 commit ef8b90b

File tree

6 files changed

+105
-40
lines changed

6 files changed

+105
-40
lines changed

src/colourscheme.ts src/diamondTheme.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
import { createTheme } from "@mui/material/styles";
22

3-
export const defaultColours = createTheme({
3+
export const diamondTheme = createTheme({
44
palette: {
55
primary: {
6-
main: "#C0C0C0",
6+
main: "#D2D2D2",
77
// light: currently calculated automatically by MUI
88
// dark: currently calculated automatically by MUI
9-
contrastText: "#FFFFFF"
9+
contrastText: "#000000"
1010
}
1111
},
1212
typography: {
13+
fontFamily: "Liberation Sans",
14+
fontSize: 14,
1315
button: {
1416
textTransform: "none"
1517
}

src/ui/widgets/ActionButton/__snapshots__/actionButton.test.tsx.snap

+19-11
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,30 @@
22

33
exports[`<ActionButton /> > it matches the snapshot 1`] = `
44
<button
5-
className="_actionbutton_b413d3"
5+
className="MuiButtonBase-root MuiButton-root MuiButton-contained MuiButton-containedPrimary MuiButton-sizeMedium MuiButton-containedSizeMedium MuiButton-colorPrimary MuiButton-fullWidth MuiButton-root MuiButton-contained MuiButton-containedPrimary MuiButton-sizeMedium MuiButton-containedSizeMedium MuiButton-colorPrimary MuiButton-fullWidth css-q0v14n-MuiButtonBase-root-MuiButton-root"
6+
disabled={false}
7+
onBlur={[Function]}
68
onClick={[MockFunction spy]}
7-
style={
8-
{
9-
"backgroundColor": undefined,
10-
"color": undefined,
11-
"cursor": undefined,
12-
"visibility": undefined,
13-
"whiteSpace": "normal",
14-
}
15-
}
9+
onContextMenu={[Function]}
10+
onDragLeave={[Function]}
11+
onFocus={[Function]}
12+
onKeyDown={[Function]}
13+
onKeyUp={[Function]}
14+
onMouseDown={[Function]}
15+
onMouseLeave={[Function]}
16+
onMouseUp={[Function]}
17+
onTouchEnd={[Function]}
18+
onTouchMove={[Function]}
19+
onTouchStart={[Function]}
20+
tabIndex={0}
21+
type="button"
1622
>
1723
<span
1824
style={
1925
{
20-
"whiteSpace": "normal",
26+
"display": "block",
27+
"lineHeight": 1,
28+
"transform": "rotate(0deg)",
2129
}
2230
}
2331
>

src/ui/widgets/ActionButton/actionButton.tsx

+73-24
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, { useContext } from "react";
22
import { WidgetActions, executeActions } from "../widgetActions";
3-
import { commonCss, Widget } from "../widget";
3+
import { Widget } from "../widget";
44
import { PVComponent, PVWidgetPropType } from "../widgetProps";
55
import classes from "./actionButton.module.css";
66
import { registerWidget } from "../register";
@@ -11,17 +11,22 @@ import {
1111
ColorPropOpt,
1212
FontPropOpt,
1313
BorderPropOpt,
14-
BoolPropOpt
14+
BoolPropOpt,
15+
FuncPropOpt,
16+
FloatPropOpt
1517
} from "../propTypes";
1618
import { Color } from "../../../types/color";
1719
import { Font } from "../../../types/font";
18-
import { Border, BorderStyle } from "../../../types/border";
20+
import { Border } from "../../../types/border";
1921
import { MacroContext } from "../../../types/macros";
2022
import { ExitFileContext, FileContext } from "../../../misc/fileContext";
23+
import { styled, Button as MuiButton } from "@mui/material";
24+
25+
import { diamondTheme } from "../../../diamondTheme";
2126

2227
export interface ActionButtonProps {
2328
text: string;
24-
disabled?: boolean;
29+
enabled?: boolean;
2530
onClick: (event: React.MouseEvent<HTMLButtonElement>) => void;
2631
image?: string;
2732
backgroundColor?: Color;
@@ -30,29 +35,59 @@ export interface ActionButtonProps {
3035
font?: Font;
3136
actions?: WidgetActions;
3237
visible?: boolean;
38+
rotationStep?: number;
39+
transparent?: boolean;
3340
}
3441

42+
const Button = styled(MuiButton)({
43+
"&.MuiButton-root": {
44+
display: "block",
45+
alignItems: "center",
46+
justifyContent: "center",
47+
height: "100%",
48+
width: "100%",
49+
minWidth: 0,
50+
minHeight: 0,
51+
padding: 0,
52+
overflow: "hidden",
53+
whiteSpace: "nowrap",
54+
wordBreak: "break-word",
55+
textTransform: "none"
56+
},
57+
"&.Mui-disabled": {
58+
cursor: "not-allowed",
59+
pointerEvents: "all !important"
60+
}
61+
});
62+
3563
export const ActionButtonComponent = (
3664
props: ActionButtonProps
3765
): JSX.Element => {
38-
const style = commonCss(props);
39-
if (props.disabled) {
40-
style["cursor"] = "not-allowed";
41-
}
42-
style["whiteSpace"] = "normal";
43-
// Use default button style if no border defined.
44-
if (props.border?.style === BorderStyle.None) {
45-
style["borderStyle"] = undefined;
46-
style["borderWidth"] = undefined;
47-
style["borderColor"] = undefined;
48-
style["padding"] = "0";
49-
}
66+
const {
67+
enabled = true,
68+
foregroundColor = diamondTheme.palette.primary.contrastText,
69+
rotationStep = 0,
70+
transparent = false
71+
} = props;
72+
73+
const backgroundColor = transparent
74+
? "transparent"
75+
: (props.backgroundColor?.toString() ?? diamondTheme.palette.primary.main);
76+
const font = props.font?.css() ?? diamondTheme.typography;
77+
const border = props.border?.css() ?? null;
78+
5079
return (
51-
<button
52-
className={classes.actionbutton}
53-
disabled={props.disabled}
80+
<Button
81+
variant={transparent ? "text" : "contained"}
82+
disabled={!enabled}
83+
fullWidth={true}
84+
sx={{
85+
color: foregroundColor.toString(),
86+
backgroundColor: backgroundColor,
87+
border: border,
88+
fontFamily: font
89+
}}
5490
onClick={props.onClick}
55-
style={style}
5691
>
5792
{props.image !== undefined ? (
5893
<figure className={classes.figure}>
@@ -64,9 +99,17 @@ export const ActionButtonComponent = (
6499
<figcaption>{props.text}</figcaption>
65100
</figure>
66101
) : (
67-
<span style={{ whiteSpace: "normal" }}>{props.text || ""}</span>
102+
<span
103+
style={{
104+
display: "block",
105+
lineHeight: 1,
106+
transform: `rotate(${rotationStep * -90}deg)`
107+
}}
108+
>
109+
{props.text ?? ""}
110+
</span>
68111
)}
69-
</button>
112+
</Button>
70113
);
71114
};
72115

@@ -78,7 +121,11 @@ const ActionButtonPropType = {
78121
foregroundColor: ColorPropOpt,
79122
font: FontPropOpt,
80123
border: BorderPropOpt,
81-
visible: BoolPropOpt
124+
visible: BoolPropOpt,
125+
enabled: BoolPropOpt,
126+
onClick: FuncPropOpt,
127+
transparent: BoolPropOpt,
128+
rotationStep: FloatPropOpt
82129
};
83130

84131
const ActionButtonWidgetProps = {
@@ -106,7 +153,7 @@ export const ActionButtonWidget = (
106153
return (
107154
<ActionButtonComponent
108155
text={props.text ?? ""}
109-
disabled={props.readonly}
156+
enabled={props.enabled}
110157
onClick={onClick}
111158
image={props.image}
112159
backgroundColor={props.backgroundColor}
@@ -115,6 +162,8 @@ export const ActionButtonWidget = (
115162
border={props.border}
116163
actions={props.actions as WidgetActions}
117164
visible={props.visible}
165+
transparent={props.transparent}
166+
rotationStep={props.rotationStep}
118167
/>
119168
);
120169
};

src/ui/widgets/EmbeddedDisplay/bobParser.test.ts

+3
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ describe("opi widget parser", (): void => {
3737
<x>10</x>
3838
<y>20</y>
3939
<not_a_property>hello</not_a_property>
40+
<transparent>true</transparent>
4041
<wrap_words>false</wrap_words>
42+
<rotation_step>1</rotation_step>
4143
</widget>
4244
</display>`;
4345

@@ -58,6 +60,7 @@ describe("opi widget parser", (): void => {
5860
// Unrecognised property not passed on.
5961
expect(widget.not_a_property).toEqual(undefined);
6062
expect(widget.wrapWords).toEqual(false);
63+
expect(widget.transparent).toEqual(true);
6164
});
6265

6366
const readbackString = `

src/ui/widgets/EmbeddedDisplay/bobParser.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,8 @@ export function parseBob(
379379
fallbackSymbol: ["fallback_symbol", opiParseString],
380380
rotation: ["rotation", bobParseNumber],
381381
styleOpt: ["style", bobParseNumber],
382-
lineColor: ["line_color", opiParseColor]
382+
lineColor: ["line_color", opiParseColor],
383+
rotationStep: ["rotation_step", bobParseNumber]
383384
};
384385

385386
const complexParsers = {

src/ui/widgets/EmbeddedDisplay/embeddedDisplay.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import { GroupBoxComponent } from "../GroupBox/groupBox";
2424
import { useOpiFile } from "./useOpiFile";
2525
import { useId } from "react-id-generator";
2626
import { getOptionalValue, trimFromString } from "../utils";
27+
import { ThemeProvider } from "@mui/material";
28+
import { diamondTheme } from "../../../diamondTheme";
2729

2830
const RESIZE_STRINGS = [
2931
"scroll-widget",
@@ -209,7 +211,7 @@ export const EmbeddedDisplay = (
209211
return (
210212
<MacroContext.Provider value={embeddedDisplayMacroContext}>
211213
<GroupBoxComponent name={resolvedName} styleOpt={0}>
212-
{component}
214+
<ThemeProvider theme={diamondTheme}>{component}</ThemeProvider>
213215
</GroupBoxComponent>
214216
</MacroContext.Provider>
215217
);

0 commit comments

Comments
 (0)