Skip to content

Commit

Permalink
Dark mode (#67)
Browse files Browse the repository at this point in the history
* Add dark mode

* Fix suggestions, lint & format

* Test dark mode

* Formatting

* Update JS file
  • Loading branch information
ThomasdenH authored Feb 18, 2025
1 parent 733e997 commit 0574642
Show file tree
Hide file tree
Showing 18 changed files with 16,089 additions and 3,259 deletions.
4 changes: 4 additions & 0 deletions frontend/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ const router = createHashRouter([
]);

const theme = createTheme({
cssVariables: true,
colorSchemes: {
dark: true,
},
typography: {
fontFamily: "",
},
Expand Down
5 changes: 3 additions & 2 deletions frontend/src/components/Dashboard.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Card, MenuItem, Select, Stack, SxProps, Theme } from "@mui/material";
import { Card, MenuItem, Select, Stack, SxProps, Theme, useTheme } from "@mui/material";
import React from "react";
import { NumberParam, useQueryParam, withDefault } from "use-query-params";

interface DashboardProps {
children?: React.ReactNode;
}
export function Dashboard({ children }: DashboardProps) {
const theme = useTheme();
return (
<Stack
sx={{
Expand All @@ -15,7 +16,7 @@ export function Dashboard({ children }: DashboardProps) {
marginBottom: "-1.5em",
padding: "1.5em",
gap: 2,
backgroundColor: "#FAFBFB",
backgroundColor: theme.palette.mode === "dark" ? undefined : "#FAFBFB",
}}
>
{children}
Expand Down
12 changes: 10 additions & 2 deletions frontend/src/components/EChart.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useTheme } from "@mui/material/styles";
import * as echarts from "echarts";
import { CSSProperties, useEffect, useRef } from "react";

Expand All @@ -10,6 +11,8 @@ interface EChartProps {
export function EChart({ width, height, option }: EChartProps) {
const ref = useRef<HTMLDivElement>(null);
const chartRef = useRef<echarts.ECharts>();
const theme = useTheme();
const themeMode = theme.palette.mode;

useEffect(() => {
if (chartRef.current) {
Expand All @@ -18,7 +21,8 @@ export function EChart({ width, height, option }: EChartProps) {

// use SVG renderer during HTML e2e tests, to compare snapshots
const renderer = window.navigator.userAgent === "puppeteer-html" ? "svg" : undefined;
const chart = echarts.init(ref.current, undefined, { renderer });
const echartsTheme = themeMode === "dark" ? "dark" : undefined;
const chart = echarts.init(ref.current, echartsTheme, { renderer });
if (option.onClick) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
chart.on("click", (option as any).onClick);
Expand All @@ -30,9 +34,13 @@ export function EChart({ width, height, option }: EChartProps) {
option.animation = false;
}

if (themeMode == "dark" && option.backgroundColor === undefined) {
option.backgroundColor = "transparent";
}

chart.setOption(option);
chartRef.current = chart;
}, [option]);
}, [option, themeMode]);

return <div ref={ref} style={{ width, height }}></div>;
}
9 changes: 6 additions & 3 deletions frontend/src/components/InvestmentsSelection.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import CheckBoxIcon from "@mui/icons-material/CheckBox";
import CheckBoxOutlineBlankIcon from "@mui/icons-material/CheckBoxOutlineBlank";
import { Autocomplete, Checkbox, Chip, SxProps, TextField } from "@mui/material";
import { Autocomplete, Checkbox, Chip, SxProps, TextField, useTheme } from "@mui/material";
import { amber, blue, grey, teal } from "@mui/material/colors";
import { SyntheticEvent } from "react";
import { useToolbarContext } from "./Header/ToolbarProvider";
Expand All @@ -23,6 +23,7 @@ interface InvestmentsSelectionProps {
export function InvestmentsSelection(props: InvestmentsSelectionProps) {
const { investments, setInvestments, types, label } = props;
const { config } = useToolbarContext();
const theme = useTheme();

const options: InvestmentOption[] = [];
if (!types || types.includes("Group")) {
Expand Down Expand Up @@ -70,6 +71,8 @@ export function InvestmentsSelection(props: InvestmentsSelectionProps) {
setInvestments(value.map((i) => i.id));
};

const chipBackgroundColor = theme.palette.mode === "dark" ? "background.default" : grey[100];

return (
<Autocomplete
multiple
Expand Down Expand Up @@ -103,14 +106,14 @@ export function InvestmentsSelection(props: InvestmentsSelectionProps) {
key={option.id}
label={option.chipLabel}
variant="outlined"
sx={{ backgroundColor: grey[100], border: `1px solid ${investmentColors[option.type]}` }}
sx={{ backgroundColor: chipBackgroundColor, border: `1px solid ${investmentColors[option.type]}` }}
{...tagProps}
/>
);
})
}
style={{ width: 600 }}
renderInput={(params) => <TextField {...params} label={label} />}
renderInput={(params) => <TextField {...params} label={label} className="investment-selection" />}
/>
);
}
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19,196 changes: 15,992 additions & 3,204 deletions frontend/tests/e2e/__snapshots__/pages.test.ts.snap

Large diffs are not rendered by default.

40 changes: 28 additions & 12 deletions frontend/tests/e2e/pages.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,30 @@ import "jest-puppeteer";

const BASE_URL = "http://127.0.0.1:5000/beancount/extension/FavaPortfolioReturns/";
const tests = [
{ name: "Portfolio", url: "" },
{ name: "Performance", url: "#/performance?compareWith=c:VHT_c:GLD" },
{ name: "Performance (TWR)", url: "#/performance?investments=g:Gold&method=twr&compareWith=c:GLD" },
{ name: "Returns", url: "#/returns" },
{ name: "Returns (MDM)", url: "#/returns?method=mdm" },
{ name: "Returns (TWR)", url: "#/returns?method=twr" },
{ name: "Dividends", url: "#/dividends" },
{ name: "Cash Flows", url: "#/cash_flows?investments=c:VHT" },
{ name: "Groups", url: "#/groups" },
{ name: "Investments", url: "#/investments" },
{ name: "Portfolio", mode: "light", url: "" },
{ name: "Performance", mode: "light", url: "#/performance?compareWith=c:VHT_c:GLD" },
{ name: "Performance (TWR)", mode: "light", url: "#/performance?investments=g:Gold&method=twr&compareWith=c:GLD" },
{ name: "Returns", mode: "light", url: "#/returns" },
{ name: "Returns (MDM)", mode: "light", url: "#/returns?method=mdm" },
{ name: "Returns (TWR)", mode: "light", url: "#/returns?method=twr" },
{ name: "Dividends", mode: "light", url: "#/dividends" },
{ name: "Cash Flows", mode: "light", url: "#/cash_flows?investments=c:VHT" },
{ name: "Groups", mode: "light", url: "#/groups" },
{ name: "Investments", mode: "light", url: "#/investments" },
{ name: "Portfolio (dark)", mode: "dark", url: "" },
{ name: "Performance (dark)", mode: "dark", url: "#/performance?compareWith=c:VHT_c:GLD" },
{
name: "Performance (TWR) (dark)",
mode: "dark",
url: "#/performance?investments=g:Gold&method=twr&compareWith=c:GLD",
},
{ name: "Returns (dark)", mode: "dark", url: "#/returns" },
{ name: "Returns (MDM) (dark)", mode: "dark", url: "#/returns?method=mdm" },
{ name: "Returns (TWR) (dark)", mode: "dark", url: "#/returns?method=twr" },
{ name: "Dividends (dark)", mode: "dark", url: "#/dividends" },
{ name: "Cash Flows (dark)", mode: "dark", url: "#/cash_flows?investments=c:VHT" },
{ name: "Groups (dark)", mode: "dark", url: "#/groups" },
{ name: "Investments (dark)", mode: "dark", url: "#/investments" },
];

function customSnapshotIdentifier(p: { currentTestName: string }) {
Expand All @@ -30,7 +44,8 @@ describe("PNG Snapshot Tests", () => {
await page.setUserAgent("puppeteer-png");
});

it.each(tests)("$name", async ({ url }) => {
it.each(tests)("$name", async ({ mode, url }) => {
await page.emulateMediaFeatures([{ name: "prefers-color-scheme", value: mode }]);
await page.goto(`${BASE_URL}${url}`);
await page.evaluate(() => {
// full page screenshot doesn't work due to sticky sidebar
Expand All @@ -48,7 +63,8 @@ describe("HTML Snapshot Tests", () => {
await page.setUserAgent("puppeteer-html");
});

it.each(tests)("$name", async ({ url }) => {
it.each(tests)("$name", async ({ url, mode }) => {
await page.emulateMediaFeatures([{ name: "prefers-color-scheme", value: mode }]);
await page.goto(`${BASE_URL}${url}`);
await page.waitForNetworkIdle();

Expand Down
72 changes: 36 additions & 36 deletions src/fava_portfolio_returns/FavaPortfolioReturns.js

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions src/fava_portfolio_returns/templates/style.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
.headerline .active {
color: #333;
}

@media (prefers-color-scheme: dark) {
.headerline .active {
color: var(--mui-palette-text-primary);
}

.investment-selection input {
background: none;
}
}

0 comments on commit 0574642

Please sign in to comment.