rename theme

This commit is contained in:
Sidney Alcantara
2021-08-26 15:43:15 +10:00
parent 941883235f
commit 9f53b5d68c
4 changed files with 1047 additions and 0 deletions

178
www/src/theme/colors.ts Normal file
View File

@@ -0,0 +1,178 @@
import { ThemeOptions } from "@material-ui/core/styles";
import { Shadows } from "@material-ui/core/styles/shadows";
import { colord, extend } from "colord";
import lchPlugin from "colord/plugins/lch";
extend([lchPlugin]);
declare module "@material-ui/core/styles" {
interface Palette {
input: string;
}
interface PaletteOptions {
input?: string;
}
}
export const PRIMARY = "#420AFD";
// export const PRIMARY = "#ED4747";
// export const PRIMARY = "#FA0";
// export const PRIMARY = "#0F0";
// export const PRIMARY = "#F15A29";
// export const PRIMARY = "#c4492c";
// export const PRIMARY = "#0070EB";
// export const PRIMARY = "#015FB8";
// export const PRIMARY = "#E8016D";
export const ERROR = "#B00020"; // https://material.io/design/color/dark-theme.html#ui-application
export const DARK_PRIMARY = "#B0B6FD"; // l: 75, c: 65, h: 275
export const colorsLight = (
_primary: Parameters<typeof colord>[0] = PRIMARY
): ThemeOptions => {
const primary = colord(_primary);
const h = primary.toLch().h;
const secondary = colord({ l: 10, c: 20, h });
const secondaryDark = colord({ l: 0, c: 0, h });
const bgDefault = colord({ l: 98, c: 2, h });
const shadowBase = colord({ l: 0, c: 20, h });
const tooltip = shadowBase.alpha(0.8);
return {
palette: {
primary: { main: primary.toHslString() },
secondary: {
main: secondary.toHslString(),
dark: secondaryDark.toHslString(),
},
error: { main: ERROR },
success: { light: "#34c759", main: "#00802e", dark: "#105e24" },
background: { default: bgDefault.toHslString() },
divider: shadowBase.alpha(0.12).toRgbString(), // Using hsl string breaks table borders
input: "#fff",
},
shadows: new Array(25).fill(undefined).map((_, i) => {
// Based on https://tailwindcss.com/docs/box-shadow
// with additional “outline” shadow
// and bigger shadow from https://github.com/outline/outline/blob/37fd7ec97a496094077a59f4d10fa0081516e3ef/shared/theme.js#L148
if (i === 0) return "none";
if (i < 4)
// prettier-ignore
return `0 0 0 1px ${shadowBase.alpha(0.04).toHslString()}, 0 1px 3px 0 ${shadowBase.alpha(0.1).toHslString()}, 0 1px 2px 0 ${shadowBase.alpha(0.06).toHslString()}`;
if (i < 8)
// prettier-ignore
return `0 0 0 1px ${shadowBase.alpha(0.05).toHslString()}, 0 4px 6px -1px ${shadowBase.alpha(0.1).toHslString()}, 0 2px 4px ${shadowBase.alpha(0.06).toHslString()}`;
if (i < 16)
// prettier-ignore
return `0 0 0 1px ${shadowBase.alpha(0.06).toHslString()}, 0 10px 15px -3px ${shadowBase.alpha(0.1).toHslString()}, 0 4px 6px ${shadowBase.alpha(0.05).toHslString()}, 0 30px 40px ${shadowBase.alpha(0.05).toHslString()}`;
if (i < 24)
// prettier-ignore
return `0 0 0 1px ${shadowBase.alpha(0.08).toHslString()}, 0 20px 25px -5px ${shadowBase.alpha(0.1).toHslString()}, 0 10px 10px ${shadowBase.alpha(0.04).toHslString()}, 0 40px 60px ${shadowBase.alpha(0.06).toHslString()}`;
else
// prettier-ignore
return `0 0 0 1px ${shadowBase.alpha(0.08).toHslString()}, 0 25px 50px -12px ${shadowBase.alpha(0.25).toHslString()}, 0 50px 80px ${shadowBase.alpha(0.06).toHslString()}`;
}) as Shadows,
components: {
MuiBackdrop: {
styleOverrides: {
root: {
backgroundColor: colord({ l: 0, c: 1, h }).alpha(0.6).toHslString(),
},
invisible: { backgroundColor: "transparent" },
},
},
MuiTooltip: {
styleOverrides: {
tooltip: { backgroundColor: tooltip.toHslString() },
},
},
MuiSlider: {
styleOverrides: {
valueLabel: { backgroundColor: secondary.toHslString() },
},
},
},
};
};
export const colorsDark = (
_primary: Parameters<typeof colord>[0] = DARK_PRIMARY
): ThemeOptions => {
const primary = colord(_primary);
const h = primary.toLch().h;
const secondary = colord({ l: 96, c: 1, h });
const bgDefault = colord({ l: 5, c: 2, h });
const bgPaper = colord({ l: 5, c: 2, h });
const shadowBase = colord({ l: 0, c: 2, h });
return {
palette: {
mode: "dark",
primary: { main: primary.toHslString() },
secondary: { main: secondary.toHslString() },
background: {
default: bgDefault.toHslString(),
paper: bgPaper.toHslString(),
},
error: {
main: colord({
l: 65,
c: 72,
h: colord(ERROR).toLch().h,
}).toHslString(),
},
action: {
hover: "rgba(255, 255, 255, 0.08)",
hoverOpacity: 0.08,
},
// success: { light: "#34c759" },
// input: "rgba(255, 255, 255, 0.24)",
input: "rgba(255, 255, 255, 0.06)",
},
shadows: new Array(25).fill(undefined).map((_, i) => {
// Based on https://tailwindcss.com/docs/box-shadow
// with additional “outline” shadow
// and bigger shadow from https://github.com/outline/outline/blob/37fd7ec97a496094077a59f4d10fa0081516e3ef/shared/theme.js#L148
if (i === 0) return "none";
if (i < 4)
// prettier-ignore
return `0 0 0 1px ${shadowBase.alpha(0.04 * 4).toHslString()}, 0 1px 3px 0 ${shadowBase.alpha(0.1 * 4).toHslString()}, 0 1px 2px 0 ${shadowBase.alpha(0.06 * 4).toHslString()}`;
if (i < 8)
// prettier-ignore
return `0 0 0 1px ${shadowBase.alpha(0.05 * 4).toHslString()}, 0 4px 6px -1px ${shadowBase.alpha(0.1 * 4).toHslString()}, 0 2px 4px ${shadowBase.alpha(0.06 * 4).toHslString()}`;
if (i < 16)
// prettier-ignore
return `0 0 0 1px ${shadowBase.alpha(0.06 * 4).toHslString()}, 0 10px 15px -3px ${shadowBase.alpha(0.1 * 4).toHslString()}, 0 4px 6px ${shadowBase.alpha(0.05 * 4).toHslString()}, 0 30px 40px ${shadowBase.alpha(0.05 * 4).toHslString()}`;
if (i < 24)
// prettier-ignore
return `0 0 0 1px ${shadowBase.alpha(0.08 * 4).toHslString()}, 0 20px 25px -5px ${shadowBase.alpha(0.1 * 4).toHslString()}, 0 10px 10px ${shadowBase.alpha(0.04 * 4).toHslString()}, 0 40px 60px ${shadowBase.alpha(0.06 * 4).toHslString()}`;
else
// prettier-ignore
return `0 0 0 1px ${shadowBase.alpha(0.08 * 4).toHslString()}, 0 25px 50px -12px ${shadowBase.alpha(0.25 * 4).toHslString()}, 0 50px 80px ${shadowBase.alpha(0.06 * 4).toHslString()}`;
}) as Shadows,
components: {
MuiBackdrop: {
styleOverrides: {
root: {
backgroundColor: colord({ l: 0, c: 1, h }).alpha(0.6).toHslString(),
},
invisible: { backgroundColor: "transparent" },
},
},
},
};
};

View File

@@ -0,0 +1,575 @@
import { Theme, ThemeOptions } from "@material-ui/core/styles";
import { colord, extend } from "colord";
import mixPlugin from "colord/plugins/mix";
extend([mixPlugin]);
declare module "@material-ui/core/styles/createTransitions" {
interface Easing {
strong: string;
}
}
export const components = (theme: Theme): ThemeOptions => {
const colorDividerHalf = colord(theme.palette.divider)
.alpha(colord(theme.palette.divider).alpha() / 2)
.toHslString();
const buttonPrimaryHover = colord(theme.palette.primary.main)
.mix(theme.palette.primary.contrastText, 0.12)
.alpha(1)
.toHslString();
const buttonSecondaryHover = colord(theme.palette.secondary.main)
.mix(theme.palette.secondary.contrastText, 0.12)
.alpha(1)
.toHslString();
const fabBackgroundColor =
theme.palette.mode === "dark"
? colord(theme.palette.background.default)
.mix(theme.palette.action.selected, 0.24)
.alpha(1)
.toHslString()
: theme.palette.background.paper;
const transitionEasingStrong = "cubic-bezier(0.85, 0, 0, 1)"; // https://docs.microsoft.com/en-us/windows/apps/design/signature-experiences/motion#animation-properties
return {
transitions: {
easing: { strong: transitionEasingStrong },
},
components: {
MuiContainer: {
defaultProps: { maxWidth: "xl" },
},
MuiPaper: {
styleOverrides: {
rounded: { borderRadius: (theme.shape.borderRadius as number) * 2 },
},
},
MuiDialog: {
styleOverrides: {
paper: { borderRadius: (theme.shape.borderRadius as number) * 2 },
},
},
MuiSnackbar: {
styleOverrides: {
root: {
left: `calc(env(safe-area-inset-left) + ${theme.spacing(1)})`,
bottom: `calc(env(safe-area-inset-bottom) + ${theme.spacing(1)})`,
},
},
},
MuiSnackbarContent: {
styleOverrides: {
root: {
borderRadius: (theme.shape.borderRadius as number) * 2,
backgroundColor: theme.palette.secondary.main,
},
},
},
MuiTextField: {
defaultProps: {
variant: "filled",
size: "small",
},
},
MuiInputBase: {
styleOverrides: {
inputSizeSmall: theme.typography.body2,
},
},
MuiFilledInput: {
styleOverrides: {
root: {
backgroundColor: theme.palette.input,
"&:hover:not(.Mui-disabled), &:focus, &.Mui-focused": {
backgroundColor: theme.palette.input,
},
boxShadow: `0 0 0 1px ${
theme.palette.mode === "dark"
? colorDividerHalf
: theme.palette.divider
} inset`,
borderRadius: theme.shape.borderRadius,
overflow: "hidden",
"&::before": {
borderRadius: theme.shape.borderRadius,
height: (theme.shape.borderRadius as number) * 2,
borderColor: theme.palette.text.disabled,
},
"&.Mui-focused::before, &.Mui-focused:hover::before": {
borderColor: theme.palette.primary.main,
},
"&.Mui-disabled": {
backgroundColor:
theme.palette.mode === "dark"
? "transparent"
: theme.palette.action.disabledBackground,
},
},
colorSecondary: {
"&.Mui-focused::before, &.Mui-focused:hover::before": {
borderColor: theme.palette.secondary.main,
},
},
inputSizeSmall: {
padding: "6px 12px",
height: 20,
},
multiline: { padding: 0 },
},
},
MuiInputLabel: {
defaultProps: {
shrink: true,
},
styleOverrides: {
filled: {
"&, &.MuiInputLabel-shrink": { transform: "none" },
position: "static",
padding: "2px 12px",
pointerEvents: "auto",
maxWidth: "none",
overflow: "visible",
whiteSpace: "normal",
...theme.typography.caption,
fontWeight: 500,
},
},
},
MuiSelect: {
styleOverrides: {
select: {
// If Select option is a MenuItem, dont add spacing
"& > *": {
margin: 0,
paddingTop: 0,
paddingBottom: 0,
},
},
icon: {
transition: theme.transitions.create("transform", {
duration: theme.transitions.duration.short,
}),
},
iconOpen: { transform: "rotate(180deg)" },
},
},
MuiListItem: {
styleOverrides: {
root: {
width: `calc(100% - ${theme.spacing(2)})`,
margin: theme.spacing(0.5, 1),
padding: theme.spacing(0.5, 1),
borderRadius: theme.shape.borderRadius,
},
},
defaultProps: { dense: true },
},
MuiMenu: {
styleOverrides: {
list: { padding: theme.spacing(0.5, 0) },
},
},
MuiMenuItem: {
styleOverrides: {
root: {
width: `calc(100% - ${theme.spacing(1)})`,
margin: theme.spacing(0, 0.5),
padding: theme.spacing(0.75, 0.75, 0.75, 1.5),
minHeight: 32,
borderRadius: theme.shape.borderRadius,
"&.Mui-selected": {
backgroundColor: theme.palette.action.selected,
"&::before": {
content: "''",
display: "block",
position: "absolute",
top: (32 - 16) / 2,
left: 0,
width: 3,
height: 16,
borderRadius: 1.5,
backgroundColor: theme.palette.primary.main,
},
},
"& + .MuiDivider-root": {
marginTop: theme.spacing(0.5),
marginBottom: theme.spacing(0.5),
},
},
},
defaultProps: { dense: true },
},
MuiListSubheader: {
defaultProps: { disableSticky: true },
styleOverrides: {
root: {
...theme.typography.subtitle2,
color: theme.palette.text.primary,
lineHeight: "32px",
userSelect: "none",
},
},
},
MuiListItemIcon: {
styleOverrides: {
root: {
".Mui-selected &": { color: "inherit" },
},
},
},
MuiListItemSecondaryAction: {
styleOverrides: {
root: { right: theme.spacing(0.75) },
},
},
MuiButton: {
styleOverrides: {
root: {
minHeight: 32,
paddingTop: theme.spacing(0.5),
paddingBottom: theme.spacing(0.5),
},
sizeSmall: {
minHeight: 28,
paddingTop: theme.spacing(0.25),
paddingBottom: theme.spacing(0.25),
},
sizeLarge: {
minHeight: 48,
fontSize: "1rem",
borderRadius: (theme.shape.borderRadius as number) * (16 / 14),
},
outlined: {
"&, &:hover, &.Mui-disabled": { border: "none" },
boxShadow:
theme.palette.mode === "dark"
? `0 0 0 1px ${colorDividerHalf} inset,
0 1px 0 0 ${colorDividerHalf} inset`
: `0 0 0 1px ${theme.palette.divider} inset,
0 -1px 0 0 ${theme.palette.divider} inset`,
backgroundColor: theme.palette.input,
"&.Mui-disabled": {
boxShadow: `0 0 0 1px ${theme.palette.divider} inset`,
backgroundColor: "transparent",
},
},
outlinedPrimary: {
"&:hover": {
backgroundColor: colord(theme.palette.input)
.mix(
theme.palette.primary.main,
theme.palette.action.hoverOpacity
)
.toHslString(),
},
},
outlinedSecondary: {
"&:hover": {
backgroundColor: colord(theme.palette.input)
.mix(
theme.palette.secondary.main,
theme.palette.action.hoverOpacity
)
.toHslString(),
},
},
contained: {
boxShadow: `${theme.shadows[2]}, 0 -1px 0 0 rgba(0, 0, 0, 0.12) inset`,
},
containedPrimary: {
"&:hover": { backgroundColor: buttonPrimaryHover },
},
containedSecondary: {
"&:hover": { backgroundColor: buttonSecondaryHover },
},
},
},
MuiButtonGroup: {
styleOverrides: {
grouped: { minWidth: 32 },
},
},
MuiIconButton: {
defaultProps: {
TouchRippleProps: { center: false },
},
styleOverrides: {
sizeSmall: { borderRadius: theme.shape.borderRadius },
},
},
MuiFab: {
styleOverrides: {
root: {
"&:not(.MuiFab-primary):not(.MuiFab-secondary):not(.Mui-disabled)": {
backgroundColor: fabBackgroundColor,
color: theme.palette.text.primary,
"&:hover": {
backgroundColor: colord(fabBackgroundColor)
.mix(
theme.palette.action.hover,
theme.palette.action.hoverOpacity
)
.alpha(1)
.toHslString(),
},
},
"&.Mui-disabled": {
backgroundColor: colord(theme.palette.background.default)
.mix(
theme.palette.action.disabledBackground,
colord(theme.palette.action.disabledBackground).alpha()
)
.alpha(1)
.toHslString(),
},
},
primary: {
boxShadow: `${theme.shadows[6]}, 0 -1px 0 0 rgba(0, 0, 0, 0.12) inset`,
"&:hover": { backgroundColor: buttonPrimaryHover },
},
secondary: {
boxShadow: `${theme.shadows[6]}, 0 -1px 0 0 rgba(0, 0, 0, 0.12) inset`,
"&:hover": { backgroundColor: buttonSecondaryHover },
},
sizeSmall: { width: 36, height: 36 },
},
},
MuiChip: {
defaultProps: { size: "small" },
styleOverrides: {
sizeMedium: {
height: "auto",
minHeight: 32,
padding: "4px 0",
"&.MuiChip-outlined": { padding: "3px 0" },
},
sizeSmall: {
height: "auto",
minHeight: 24,
padding: "2px 0",
"&.MuiChip-outlined": { padding: "1px 0" },
},
clickable: {
"&.MuiChip-filledPrimary:hover": {
backgroundColor: buttonPrimaryHover,
},
"&.MuiChip-filledSecondary:hover": {
backgroundColor: buttonSecondaryHover,
},
},
},
},
MuiSwitch: {
defaultProps: { size: "small" },
styleOverrides: {
sizeMedium: {
width: 42 + (38 - 24),
height: 24 + (38 - 24),
padding: (38 - 24) / 2,
"& .MuiSwitch-thumb": { width: 16, height: 16 },
"& .MuiSwitch-switchBase": { padding: 11 },
},
sizeSmall: {
width: 36 + (28 - 20),
height: 20 + (28 - 20),
padding: (28 - 20) / 2,
"& .MuiSwitch-thumb": { width: 12, height: 12 },
"& .MuiSwitch-switchBase": { padding: 8 },
},
track: {
borderRadius: 24 / 2,
backgroundColor: "transparent",
boxShadow: `0 0 0 1px ${theme.palette.text.disabled} inset`,
".Mui-disabled + &": {
backgroundColor: theme.palette.text.disabled,
},
opacity: 1,
".MuiSwitch-switchBase.Mui-checked:not(.Mui-disabled) + &": {
opacity: 1,
},
".MuiSwitch-switchBase.Mui-checked + &": {
boxShadow: "none",
},
},
switchBase: {
color: theme.palette.text.primary,
"&.Mui-checked": { transform: "translateX(18px)" },
},
thumb: {
borderRadius: 24 / 2,
boxShadow: theme.shadows[1],
background: theme.palette.text.secondary,
".MuiSwitch-switchBase.Mui-checked &": {
backgroundColor: theme.palette.secondary.contrastText,
},
transition: theme.transitions.create(
["width", "transform", "background-color"],
{ duration: theme.transitions.duration.shortest }
),
".MuiSwitch-root:hover .MuiSwitch-switchBase:not(.Mui-disabled) &": {
transform: `scale(${1 + 2 / 16})`,
},
".MuiSwitch-root.MuiSwitch-sizeSmall:hover .MuiSwitch-switchBase:not(.Mui-disabled) &": {
transform: `scale(${1 + 2 / 12})`,
},
".MuiSwitch-root:active .MuiSwitch-switchBase:not(.Mui-disabled) &": {
width: 16 + 4,
},
".MuiSwitch-root.MuiSwitch-sizeSmall:active .MuiSwitch-switchBase:not(.Mui-disabled) &": {
width: 12 + 4,
},
"& + .MuiTouchRipple-root": {
borderRadius: 24 / 2,
zIndex: -1,
},
".MuiSwitch-root:active .MuiSwitch-switchBase.Mui-checked:not(.Mui-disabled) &": {
transform: `translateX(-4px) scale(${1 + 2 / 16})`,
"& + .MuiTouchRipple-root": { left: -4 },
},
".MuiSwitch-root.MuiSwitch-sizeSmall:active .MuiSwitch-switchBase.Mui-checked:not(.Mui-disabled) &": {
transform: `translateX(-4px) scale(${1 + 2 / 12})`,
},
".MuiSwitch-switchBase.Mui-disabled &": {
opacity: theme.palette.action.disabledOpacity,
},
".MuiSwitch-switchBase.Mui-disabled.Mui-checked &": {
opacity: 1,
},
},
colorSuccess: {
"&.Mui-checked": {
color: theme.palette.success.light,
"& + .MuiSwitch-track": {
backgroundColor: theme.palette.success.light,
},
},
},
} as any,
},
MuiSlider: {
styleOverrides: {
thumb: {
color: theme.palette.common.white,
transformOrigin: "50% 50%",
"&::before": {
boxShadow:
theme.palette.mode === "dark"
? theme.shadows[1].replace(")", ", 0.24)")
: `${theme.shadows[1]}, 0 0 0 1px ${theme.palette.divider}`,
},
"&:hover": {
"& > input": { transform: `scale(${1 + 2 / 20})` },
},
},
mark: { width: 3, height: 3 },
valueLabel: {
borderRadius: theme.shape.borderRadius,
"&::before": {
borderRadius: (theme.shape.borderRadius as number) / 2,
width: 10,
height: 10,
bottom: 1,
},
},
},
},
MuiTabs: {
defaultProps: {
TabIndicatorProps: {
children: <span className="MuiTabs-indicatorSpan" />,
},
},
styleOverrides: {
indicator: {
display: "flex",
justifyContent: "center",
alignItems: "center",
backgroundColor: "transparent",
transitionTimingFunction: transitionEasingStrong,
transitionDuration: `${theme.transitions.duration.complex}ms`,
height: 3,
".MuiTabs-vertical &": { width: 3 },
"& > .MuiTabs-indicatorSpan": {
width: "100%",
height: "100%",
maxWidth: 32,
maxHeight: 16,
borderRadius: 1.5,
backgroundColor: theme.palette.primary.main,
transition: theme.transitions.create("transform", {
duration: theme.transitions.duration.shortest,
}),
".MuiTabs-root:active &": { transform: "scaleX(1.25)" },
".MuiTabs-vertical:active &": { transform: "scaleY(1.25)" },
},
},
},
},
MuiTab: {
styleOverrides: {
root: {
borderRadius: theme.shape.borderRadius,
transition: theme.transitions.create(
["background-color", "color"],
{ duration: theme.transitions.duration.shortest }
),
"&:hover": { backgroundColor: theme.palette.action.hover },
"&.Mui-selected:hover": {
backgroundColor: colord(theme.palette.primary.main)
.alpha(theme.palette.action.hoverOpacity)
.toHslString(),
},
},
},
},
},
};
};

148
www/src/theme/palette.ts Normal file
View File

@@ -0,0 +1,148 @@
export const palette = {
aBlack: {
500: "#282829",
},
aWhite: {
500: "#ffffff",
},
aRed: {
100: "#fae4e5",
300: "#fb8c8c",
500: "#ed4747",
600: "#e91c1c",
700: "#c12929",
},
aGray: {
50: "#fafafa",
100: "#f2f2f2",
200: "#e9e9e9",
300: "#cccccc",
500: "#999999",
700: "#595959",
},
gray: {
100: "#f2f2f2",
300: "#cccccc",
500: "#999999",
700: "#595959",
},
blueGray: {
100: "#93a4ad",
300: "#647c8a",
500: "#485a63",
700: "#394c55",
},
indigo: {
100: "#7986cb",
300: "#3f51b5",
500: "#303f9f",
700: "#213092",
},
blue: {
100: "#64b5f6",
300: "#2196f3",
500: "#1976d2",
700: "#0a59a8",
},
lightBlue: {
100: "#4fc3f7",
300: "#03a9f4",
500: "#0b8ed6",
700: "#007fc5",
},
cyan: {
100: "#4dd0e1",
300: "#00bcd4",
500: "#0097a7",
700: "#258493",
},
teal: {
100: "#4db6ac",
300: "#049587",
500: "#037b6d",
700: "#006055",
},
green: {
100: "#81c784",
300: "#4caf50",
500: "#388e3c",
700: "#2e7d32",
},
lightGreen: {
100: "#aed581",
300: "#8bc34a",
500: "#689f38",
700: "#4f6f33",
},
lime: {
100: "#dce775",
300: "#cddc39",
500: "#afb42b",
700: "#8e9d01",
},
yellow: {
100: "#fff176",
300: "#ffeb3b",
500: "#fbc02d",
700: "#d07e04",
},
amber: {
100: "#ffd54f",
300: "#ffc107",
500: "#ffa000",
700: "#b38c2b",
},
orange: {
100: "#ffb74d",
300: "#ff9800",
500: "#f57c00",
700: "#bb661e",
},
brown: {
100: "#a1887f",
300: "#795548",
500: "#5d4037",
700: "#4e3229",
},
tangerine: {
100: "#ff8a65",
300: "#ff5722",
500: "#e64a19",
700: "#c0360a",
},
errorRed: {
100: "#e57373",
300: "#f44336",
500: "#d32f2f",
700: "#c62323",
},
pink: {
100: "#f06292",
300: "#e91e63",
500: "#c2185b",
700: "#b0104f",
},
purple: {
100: "#ba68c8",
300: "#9c27b0",
500: "#7b1fa2",
700: "#650e89",
},
violet: {
100: "#9575cd",
300: "#673ab7",
500: "#512da8",
700: "#341878",
},
} as const;
export const paletteToMui = (
color: Record<"700" | "300" | "500" | "100", string>
) => ({
main: color[500],
light: color[300],
dark: color[700],
});
export default palette;

146
www/src/theme/typography.ts Normal file
View File

@@ -0,0 +1,146 @@
import { ThemeOptions } from "@material-ui/core/styles";
import {
FontStyle,
TypographyStyleOptions,
} from "@material-ui/core/styles/createTypography";
declare module "@material-ui/core/styles/createTypography" {
interface FontStyle {
fontFamilyMono: string;
fontFamilyHeading: string;
}
}
export const BODY_FONT = "Inter, system-ui, sans-serif";
export const HEADING_FONT = "Space Grotesk, " + BODY_FONT;
export const MONO_FONT = "IBM Plex Mono, ui-monospace, monospace";
export const ROOT_FONT_SIZE = 16;
export const toRem = (px: number) => `${px / ROOT_FONT_SIZE}rem`;
export const toEm = (px: number, root: number) => `${px / root}em`;
export const typography = ({
fontFamily = BODY_FONT,
fontFamilyMono = MONO_FONT,
fontFamilyHeading = HEADING_FONT,
fontWeightLight = 300,
fontWeightRegular = 400,
fontWeightMedium = 500,
fontWeightBold = 600,
}: Partial<ThemeOptions["typography"] & FontStyle>): ThemeOptions => {
const fontStyleBody: TypographyStyleOptions = {
fontFamily: fontFamily,
fontFeatureSettings:
fontFamily !== BODY_FONT
? "normal"
: `"calt", "ss01", "ss03", "cv05", "cv09"`,
};
const fontStyleHeading: TypographyStyleOptions = {
fontFamily: fontFamilyHeading,
fontFeatureSettings:
fontFamilyHeading !== HEADING_FONT ? "normal" : `"ss02", "ss03"`,
};
return {
typography: {
fontFamily,
fontFamilyMono,
fontFamilyHeading,
fontWeightLight,
fontWeightRegular,
fontWeightMedium,
fontWeightBold,
h1: {
...fontStyleHeading,
fontWeight: 600,
fontSize: toRem(96),
letterSpacing: toEm(-1.5, 96),
lineHeight: 112 / 96,
},
h2: {
...fontStyleHeading,
fontWeight: 600,
fontSize: toRem(60),
letterSpacing: toEm(-0.75, 60),
lineHeight: 72 / 60,
},
h3: {
...fontStyleHeading,
fontWeight: 600,
fontSize: toRem(48),
letterSpacing: toEm(-0.5, 48),
lineHeight: 60 / 48,
},
h4: {
...fontStyleHeading,
fontWeight: 600,
fontSize: toRem(34),
letterSpacing: toEm(-0.35, 34),
lineHeight: 44 / 34,
},
h5: {
...fontStyleHeading,
fontWeight: 600,
fontSize: toRem(24),
// letterSpacing: toEm(-0.2, 24),
lineHeight: 32 / 24,
},
h6: {
...fontStyleHeading,
fontWeight: 600,
fontSize: toRem(20),
// letterSpacing: toEm(-0.15, 20),
lineHeight: 28 / 20,
},
subtitle1: {
...fontStyleHeading,
fontWeight: 600,
fontSize: toRem(16),
letterSpacing: toEm(0.2, 16),
lineHeight: 24 / 16,
},
subtitle2: {
...fontStyleHeading,
fontWeight: 600,
fontSize: toRem(14),
letterSpacing: toEm(0.25, 14),
lineHeight: 20 / 14,
},
body1: {
...fontStyleBody,
fontSize: toRem(16),
letterSpacing: toEm(0.5, 16),
lineHeight: 24 / 16,
},
body2: {
...fontStyleBody,
fontSize: toRem(14),
letterSpacing: toEm(0.25, 14),
lineHeight: 20 / 14,
},
button: {
...fontStyleBody,
fontWeight: 500,
fontSize: toRem(14),
letterSpacing: toEm(0.25, 14),
lineHeight: 20 / 14,
textTransform: "none",
},
caption: {
...fontStyleBody,
fontSize: toRem(12),
letterSpacing: toEm(0.4, 12),
lineHeight: 20 / 12,
},
overline: {
...fontStyleBody,
fontSize: toRem(12),
letterSpacing: toEm(1.5, 12),
lineHeight: 20 / 12,
},
},
};
};