Skip to content

Commit b778cef

Browse files
authored
chore: refactor validation button (#93)
* chore: refactor validation button * fix: improve how dark mode is set/determined
1 parent 36eb615 commit b778cef

File tree

3 files changed

+116
-181
lines changed

3 files changed

+116
-181
lines changed
Lines changed: 43 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,149 +1,80 @@
11
import { DeveloperService } from "../spicedb-common/services/developerservice";
2-
import Button from "@material-ui/core/Button";
3-
import { Theme, createStyles, makeStyles } from "@material-ui/core/styles";
4-
import { alpha } from "@material-ui/core/styles/colorManipulator";
5-
import CheckCircleIcon from "@material-ui/icons/CheckCircle";
6-
import CheckCircleOutlineIcon from "@material-ui/icons/CheckCircleOutline";
7-
import ErrorIcon from "@material-ui/icons/Error";
8-
import PlayCircleFilledIcon from "@material-ui/icons/PlayCircleFilled";
9-
import clsx from "clsx";
10-
import "react-reflex/styles.css";
2+
import { Button } from "./ui/button";
113
import { DataStore } from "../services/datastore";
124
import { ValidationState, ValidationStatus } from "../services/validation";
13-
import { TourElementClass } from "./GuidedTour";
5+
import { CheckCircle, CircleX, CirclePlay } from "lucide-react";
146

15-
const useStyles = makeStyles((theme: Theme) =>
16-
createStyles({
17-
gcm: {
18-
color: "green",
19-
display: "inherit",
20-
},
21-
rem: {
22-
color: "red",
23-
display: "inherit",
24-
},
25-
gray: {
26-
color: "gray",
27-
display: "inherit",
28-
},
29-
lastRun: {
30-
display: "grid",
31-
gridTemplateColumns: "auto 150px",
32-
alignItems: "center",
33-
columnGap: theme.spacing(1),
34-
backgroundColor: "rgba(255, 255, 255, 0.05)",
35-
height: "100%",
36-
padding: "4px",
37-
paddingLeft: "8px",
38-
},
39-
validated: {
40-
backgroundColor: alpha(theme.palette.success.light, 0.2),
41-
},
42-
validationError: {
43-
backgroundColor: alpha(theme.palette.error.light, 0.2),
44-
},
45-
validationDisplay: {
46-
display: "grid",
47-
gridTemplateColumns: "auto auto",
48-
alignItems: "center",
49-
columnGap: theme.spacing(1),
50-
},
51-
}),
52-
);
53-
54-
export function ValidateButton(props: {
7+
export function ValidateButton({
8+
conductValidation,
9+
datastore,
10+
validationState,
11+
developerService,
12+
}: {
5513
conductValidation: () => void;
5614
datastore: DataStore;
5715
validationState: ValidationState;
5816
developerService: DeveloperService;
5917
}) {
60-
const validated =
61-
props.validationState.status === ValidationStatus.VALIDATED ||
62-
props.validationState.status === ValidationStatus.VALIDATION_ERROR;
6318
const upToDate =
64-
validated &&
65-
props.validationState.validationDatastoreIndex ===
66-
props.datastore.currentIndex();
67-
68-
const classes = useStyles();
19+
validationState.validationDatastoreIndex === datastore.currentIndex();
20+
const valid =
21+
upToDate && validationState.status === ValidationStatus.VALIDATED;
22+
const invalid =
23+
upToDate && validationState.status === ValidationStatus.VALIDATION_ERROR;
24+
const loading = validationState.status === ValidationStatus.CALL_ERROR;
25+
const notRun =
26+
validationState.status !== ValidationStatus.CALL_ERROR && !upToDate;
6927

7028
return (
71-
<div className={classes.validationDisplay}>
72-
<div
73-
className={clsx(classes.lastRun, {
74-
[classes.validated]:
75-
upToDate &&
76-
props.validationState.status === ValidationStatus.VALIDATED,
77-
[classes.validationError]:
78-
upToDate &&
79-
props.validationState.status === ValidationStatus.VALIDATION_ERROR,
80-
})}
81-
>
29+
<div className="flex flex-row justify-between">
30+
<div className="flex flex-row px-3 mr-2 w-48 items-center bg-muted rounded-xs">
8231
<ValidationIcon
83-
datastore={props.datastore}
84-
validationState={props.validationState}
32+
datastore={datastore}
33+
validationState={validationState}
34+
className="pr-2"
8535
/>
86-
{upToDate &&
87-
props.validationState.status === ValidationStatus.VALIDATED &&
88-
"Validated!"}
89-
{upToDate &&
90-
props.validationState.status === ValidationStatus.VALIDATION_ERROR &&
91-
"Failed to Validate"}
92-
{props.validationState.status === ValidationStatus.CALL_ERROR &&
93-
"Dev service loading"}
94-
{props.validationState.status !== ValidationStatus.CALL_ERROR &&
95-
!upToDate &&
96-
"Validation not run"}
36+
{valid && "Validated!"}
37+
{invalid && "Failed to Validate"}
38+
{loading && "Dev service loading"}
39+
{notRun && "Validation not run"}
9740
</div>
9841
<Button
99-
variant="contained"
100-
startIcon={<PlayCircleFilledIcon />}
101-
className={TourElementClass.run}
10242
disabled={
103-
props.developerService.state.status !== "ready" ||
104-
props.validationState.status === ValidationStatus.RUNNING
43+
developerService.state.status !== "ready" ||
44+
validationState.status === ValidationStatus.RUNNING
10545
}
106-
onClick={props.conductValidation}
46+
onClick={conductValidation}
47+
variant="outline"
10748
>
49+
<CirclePlay />
10850
Run
10951
</Button>
11052
</div>
11153
);
11254
}
11355

114-
export function ValidationIcon(props: {
115-
small?: boolean;
56+
export function ValidationIcon({
57+
datastore,
58+
validationState,
59+
className,
60+
}: {
11661
datastore: DataStore;
11762
validationState: ValidationState;
63+
className: string;
11864
}) {
119-
const classes = useStyles();
12065
if (
121-
props.validationState.status === ValidationStatus.VALIDATED &&
122-
props.datastore.currentIndex() ===
123-
props.validationState.validationDatastoreIndex
66+
validationState.status === ValidationStatus.VALIDATED &&
67+
datastore.currentIndex() === validationState.validationDatastoreIndex
12468
) {
125-
return (
126-
<span className={classes.gcm}>
127-
<CheckCircleIcon />
128-
</span>
129-
);
69+
return <CheckCircle className={className} fill="green" />;
13070
}
13171

13272
if (
133-
props.validationState.status === ValidationStatus.VALIDATION_ERROR &&
134-
props.datastore.currentIndex() ===
135-
props.validationState.validationDatastoreIndex
73+
validationState.status === ValidationStatus.VALIDATION_ERROR &&
74+
datastore.currentIndex() === validationState.validationDatastoreIndex
13675
) {
137-
return (
138-
<span className={classes.rem}>
139-
<ErrorIcon />
140-
</span>
141-
);
76+
return <CircleX className={className} fill="red" />;
14277
}
14378

144-
return (
145-
<span className={classes.gray}>
146-
<CheckCircleOutlineIcon />
147-
</span>
148-
);
79+
return <CheckCircle className={className} />;
14980
}

src/index.css

Lines changed: 69 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
@import "tailwindcss";
22
@import "tw-animate-css";
33

4-
@custom-variant dark (&:is(.dark *));
4+
@custom-variant dark (&:where(.dark, .dark *));
55

66
body {
77
margin: 0;
@@ -52,73 +52,75 @@ code {
5252
--color-sidebar-ring: var(--sidebar-ring);
5353
}
5454

55-
:root {
56-
--radius: 0.625rem;
57-
--background: oklch(1 0 0);
58-
--foreground: oklch(0.147 0.004 49.25);
59-
--card: oklch(1 0 0);
60-
--card-foreground: oklch(0.147 0.004 49.25);
61-
--popover: oklch(1 0 0);
62-
--popover-foreground: oklch(0.147 0.004 49.25);
63-
--primary: oklch(0.216 0.006 56.043);
64-
--primary-foreground: oklch(0.985 0.001 106.423);
65-
--secondary: oklch(0.97 0.001 106.424);
66-
--secondary-foreground: oklch(0.216 0.006 56.043);
67-
--muted: oklch(0.97 0.001 106.424);
68-
--muted-foreground: oklch(0.553 0.013 58.071);
69-
--accent: oklch(0.97 0.001 106.424);
70-
--accent-foreground: oklch(0.216 0.006 56.043);
71-
--destructive: oklch(0.577 0.245 27.325);
72-
--border: oklch(0.923 0.003 48.717);
73-
--input: oklch(0.923 0.003 48.717);
74-
--ring: oklch(0.709 0.01 56.259);
75-
--chart-1: oklch(0.646 0.222 41.116);
76-
--chart-2: oklch(0.6 0.118 184.704);
77-
--chart-3: oklch(0.398 0.07 227.392);
78-
--chart-4: oklch(0.828 0.189 84.429);
79-
--chart-5: oklch(0.769 0.188 70.08);
80-
--sidebar: oklch(0.985 0.001 106.423);
81-
--sidebar-foreground: oklch(0.147 0.004 49.25);
82-
--sidebar-primary: oklch(0.216 0.006 56.043);
83-
--sidebar-primary-foreground: oklch(0.985 0.001 106.423);
84-
--sidebar-accent: oklch(0.97 0.001 106.424);
85-
--sidebar-accent-foreground: oklch(0.216 0.006 56.043);
86-
--sidebar-border: oklch(0.923 0.003 48.717);
87-
--sidebar-ring: oklch(0.709 0.01 56.259);
88-
}
55+
@layer theme {
56+
:root {
57+
--radius: 0.625rem;
58+
--background: oklch(1 0 0);
59+
--foreground: oklch(0.147 0.004 49.25);
60+
--card: oklch(1 0 0);
61+
--card-foreground: oklch(0.147 0.004 49.25);
62+
--popover: oklch(1 0 0);
63+
--popover-foreground: oklch(0.147 0.004 49.25);
64+
--primary: oklch(0.216 0.006 56.043);
65+
--primary-foreground: oklch(0.985 0.001 106.423);
66+
--secondary: oklch(0.97 0.001 106.424);
67+
--secondary-foreground: oklch(0.216 0.006 56.043);
68+
--muted: oklch(0.97 0.001 106.424);
69+
--muted-foreground: oklch(0.553 0.013 58.071);
70+
--accent: oklch(0.97 0.001 106.424);
71+
--accent-foreground: oklch(0.216 0.006 56.043);
72+
--destructive: oklch(0.577 0.245 27.325);
73+
--border: oklch(0.923 0.003 48.717);
74+
--input: oklch(0.923 0.003 48.717);
75+
--ring: oklch(0.709 0.01 56.259);
76+
--chart-1: oklch(0.646 0.222 41.116);
77+
--chart-2: oklch(0.6 0.118 184.704);
78+
--chart-3: oklch(0.398 0.07 227.392);
79+
--chart-4: oklch(0.828 0.189 84.429);
80+
--chart-5: oklch(0.769 0.188 70.08);
81+
--sidebar: oklch(0.985 0.001 106.423);
82+
--sidebar-foreground: oklch(0.147 0.004 49.25);
83+
--sidebar-primary: oklch(0.216 0.006 56.043);
84+
--sidebar-primary-foreground: oklch(0.985 0.001 106.423);
85+
--sidebar-accent: oklch(0.97 0.001 106.424);
86+
--sidebar-accent-foreground: oklch(0.216 0.006 56.043);
87+
--sidebar-border: oklch(0.923 0.003 48.717);
88+
--sidebar-ring: oklch(0.709 0.01 56.259);
89+
}
8990

90-
.dark {
91-
--background: oklch(0.147 0.004 49.25);
92-
--foreground: oklch(0.985 0.001 106.423);
93-
--card: oklch(0.216 0.006 56.043);
94-
--card-foreground: oklch(0.985 0.001 106.423);
95-
--popover: oklch(0.216 0.006 56.043);
96-
--popover-foreground: oklch(0.985 0.001 106.423);
97-
--primary: oklch(0.923 0.003 48.717);
98-
--primary-foreground: oklch(0.216 0.006 56.043);
99-
--secondary: oklch(0.268 0.007 34.298);
100-
--secondary-foreground: oklch(0.985 0.001 106.423);
101-
--muted: oklch(0.268 0.007 34.298);
102-
--muted-foreground: oklch(0.709 0.01 56.259);
103-
--accent: oklch(0.268 0.007 34.298);
104-
--accent-foreground: oklch(0.985 0.001 106.423);
105-
--destructive: oklch(0.704 0.191 22.216);
106-
--border: oklch(1 0 0 / 10%);
107-
--input: oklch(1 0 0 / 15%);
108-
--ring: oklch(0.553 0.013 58.071);
109-
--chart-1: oklch(0.488 0.243 264.376);
110-
--chart-2: oklch(0.696 0.17 162.48);
111-
--chart-3: oklch(0.769 0.188 70.08);
112-
--chart-4: oklch(0.627 0.265 303.9);
113-
--chart-5: oklch(0.645 0.246 16.439);
114-
--sidebar: oklch(0.216 0.006 56.043);
115-
--sidebar-foreground: oklch(0.985 0.001 106.423);
116-
--sidebar-primary: oklch(0.488 0.243 264.376);
117-
--sidebar-primary-foreground: oklch(0.985 0.001 106.423);
118-
--sidebar-accent: oklch(0.268 0.007 34.298);
119-
--sidebar-accent-foreground: oklch(0.985 0.001 106.423);
120-
--sidebar-border: oklch(1 0 0 / 10%);
121-
--sidebar-ring: oklch(0.553 0.013 58.071);
91+
.dark {
92+
--background: oklch(0.147 0.004 49.25);
93+
--foreground: oklch(0.985 0.001 106.423);
94+
--card: oklch(0.216 0.006 56.043);
95+
--card-foreground: oklch(0.985 0.001 106.423);
96+
--popover: oklch(0.216 0.006 56.043);
97+
--popover-foreground: oklch(0.985 0.001 106.423);
98+
--primary: oklch(0.923 0.003 48.717);
99+
--primary-foreground: oklch(0.216 0.006 56.043);
100+
--secondary: oklch(0.268 0.007 34.298);
101+
--secondary-foreground: oklch(0.985 0.001 106.423);
102+
--muted: oklch(0.268 0.007 34.298);
103+
--muted-foreground: oklch(0.709 0.01 56.259);
104+
--accent: oklch(0.268 0.007 34.298);
105+
--accent-foreground: oklch(0.985 0.001 106.423);
106+
--destructive: oklch(0.704 0.191 22.216);
107+
--border: oklch(1 0 0 / 10%);
108+
--input: oklch(1 0 0 / 15%);
109+
--ring: oklch(0.553 0.013 58.071);
110+
--chart-1: oklch(0.488 0.243 264.376);
111+
--chart-2: oklch(0.696 0.17 162.48);
112+
--chart-3: oklch(0.769 0.188 70.08);
113+
--chart-4: oklch(0.627 0.265 303.9);
114+
--chart-5: oklch(0.645 0.246 16.439);
115+
--sidebar: oklch(0.216 0.006 56.043);
116+
--sidebar-foreground: oklch(0.985 0.001 106.423);
117+
--sidebar-primary: oklch(0.488 0.243 264.376);
118+
--sidebar-primary-foreground: oklch(0.985 0.001 106.423);
119+
--sidebar-accent: oklch(0.268 0.007 34.298);
120+
--sidebar-accent-foreground: oklch(0.985 0.001 106.423);
121+
--sidebar-border: oklch(1 0 0 / 10%);
122+
--sidebar-ring: oklch(0.553 0.013 58.071);
123+
}
122124
}
123125

124126
@layer base {

src/playground-ui/PlaygroundUIThemed.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@ export default function PlaygroundUIThemed({
2121
forceDarkMode,
2222
children,
2323
}: PlaygroundUIThemedProps) {
24-
const { setTheme } = useTheme();
24+
const { theme: currentTheme, setTheme } = useTheme();
2525
// Determine whether the user prefers dark or light mode.
2626
const prefersDarkMode = useMediaQuery("(prefers-color-scheme: dark)");
27-
const darkMode = prefersDarkMode || forceDarkMode === true;
27+
const darkMode =
28+
forceDarkMode === true ||
29+
(currentTheme === "system" ? prefersDarkMode : currentTheme === "dark");
2830

2931
useEffect(() => {
3032
if (forceDarkMode) {

0 commit comments

Comments
 (0)