feat(mui): theme.ts with light/dark palettes, brand fonts, data-theme selector
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
28
src/admin/theme.test.ts
Normal file
28
src/admin/theme.test.ts
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import { describe, it, expect } from "vitest";
|
||||||
|
import { theme } from "./theme";
|
||||||
|
|
||||||
|
describe("MUI theme", () => {
|
||||||
|
it("uses the brand fonts", () => {
|
||||||
|
expect(theme.typography.fontFamily).toContain("Plus Jakarta Sans");
|
||||||
|
expect(String(theme.typography.h1.fontFamily)).toContain("Urbanist");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("maps the brand red per color scheme", () => {
|
||||||
|
expect(theme.colorSchemes.light.palette.primary.main).toBe("#c73030");
|
||||||
|
expect(theme.colorSchemes.dark.palette.primary.main).toBe("#d63031");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("maps the refreshed light canvas + paper", () => {
|
||||||
|
expect(theme.colorSchemes.light.palette.background.default).toBe("#f4f3f1");
|
||||||
|
expect(theme.colorSchemes.light.palette.background.paper).toBe("#ffffff");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("maps semantic colors per scheme", () => {
|
||||||
|
expect(theme.colorSchemes.light.palette.error.main).toBe("#b91c1c");
|
||||||
|
expect(theme.colorSchemes.dark.palette.success.main).toBe("#22c55e");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("uses the base radius of 10", () => {
|
||||||
|
expect(theme.shape.borderRadius).toBe(10);
|
||||||
|
});
|
||||||
|
});
|
||||||
56
src/admin/theme.ts
Normal file
56
src/admin/theme.ts
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import { createTheme } from "@mui/material/styles";
|
||||||
|
|
||||||
|
const FONT_BODY = "'Plus Jakarta Sans', system-ui, sans-serif";
|
||||||
|
const FONT_HEADING = "'Urbanist', sans-serif";
|
||||||
|
const FONT_MONO = "'DM Mono', Menlo, monospace";
|
||||||
|
|
||||||
|
export const theme = createTheme({
|
||||||
|
cssVariables: {
|
||||||
|
colorSchemeSelector: "[data-theme='%s']",
|
||||||
|
},
|
||||||
|
colorSchemes: {
|
||||||
|
light: {
|
||||||
|
palette: {
|
||||||
|
mode: "light",
|
||||||
|
primary: { main: "#c73030" },
|
||||||
|
success: { main: "#15803d" },
|
||||||
|
warning: { main: "#b45309" },
|
||||||
|
error: { main: "#b91c1c" },
|
||||||
|
info: { main: "#1d4ed8" },
|
||||||
|
background: { default: "#f4f3f1", paper: "#ffffff" },
|
||||||
|
text: { primary: "#1a1a1a", secondary: "#555555" },
|
||||||
|
divider: "rgba(0,0,0,0.1)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
dark: {
|
||||||
|
palette: {
|
||||||
|
mode: "dark",
|
||||||
|
primary: { main: "#d63031" },
|
||||||
|
success: { main: "#22c55e" },
|
||||||
|
warning: { main: "#f59e0b" },
|
||||||
|
error: { main: "#ef4444" },
|
||||||
|
info: { main: "#3b82f6" },
|
||||||
|
background: { default: "#0f0f0f", paper: "#1a1a1a" },
|
||||||
|
text: { primary: "#ffffff", secondary: "#a0a0a0" },
|
||||||
|
divider: "rgba(255,255,255,0.08)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
shape: { borderRadius: 10 },
|
||||||
|
typography: {
|
||||||
|
fontFamily: FONT_BODY,
|
||||||
|
h1: { fontFamily: FONT_HEADING, fontWeight: 800 },
|
||||||
|
h2: { fontFamily: FONT_HEADING, fontWeight: 800 },
|
||||||
|
h3: { fontFamily: FONT_HEADING, fontWeight: 800 },
|
||||||
|
h4: { fontFamily: FONT_HEADING, fontWeight: 700 },
|
||||||
|
h5: { fontFamily: FONT_HEADING, fontWeight: 700 },
|
||||||
|
h6: { fontFamily: FONT_HEADING, fontWeight: 700 },
|
||||||
|
button: { textTransform: "none", fontWeight: 600 },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const fonts = {
|
||||||
|
body: FONT_BODY,
|
||||||
|
heading: FONT_HEADING,
|
||||||
|
mono: FONT_MONO,
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user