Files
frontend/packages/ui/src/theme.ts
T
ksv741 ca0ad4f824
Frontend verify / commits (pull_request) Successful in 28s
Frontend verify / security (pull_request) Successful in 10s
Frontend verify / verify (pull_request) Successful in 8m19s
refactor: enforce frontend view model boundaries
2026-09-28 18:48:23 +03:00

93 lines
2.6 KiB
TypeScript

import {
colorsTuple,
createTheme,
type CSSVariablesResolver,
getThemeColor,
type MantinePrimaryShade,
Modal,
rem,
rgba,
} from "@mantine/core";
import designTokens from "@wealthledger/tokens/tokens.json";
import "./styles.css";
const { breakpoints, color, radius, shadows, spacing, typography }
= designTokens;
const mapValues = <T, U>(values: Record<string, T>, convert: (value: T) => U) =>
Object.fromEntries(
Object.entries(values).map(([name, value]) => [name, convert(value)]),
);
const colorRoles = mapValues(color.roles, role =>
role.shade === null ? role.color : `${role.color}.${role.shade}`,
);
const theme = createTheme({
black: color.base.black,
breakpoints: mapValues(
breakpoints.values,
value => `${value}${breakpoints.unit}`,
),
colors: mapValues(color.palettes, colorsTuple),
components: {
Modal: Modal.extend({
defaultProps: {
overlayProps: { blur: 3 },
transitionProps: {
duration: 220,
exitDuration: 180,
timingFunction: "ease-out",
transition: "fade-down",
},
},
}),
},
defaultRadius: radius.default,
fontFamily: typography.fontFamily,
fontFamilyMonospace: typography.fontFamilyMonospace,
fontSizes: mapValues(typography.fontSizes, value => rem(value)),
fontWeights: mapValues(typography.fontWeights, String),
headings: {
fontFamily: typography.fontFamily,
fontWeight: String(typography.fontWeights.bold),
sizes: mapValues(typography.headings, value => ({
fontSize: rem(value.fontSize),
lineHeight: String(value.lineHeight),
})),
},
lineHeights: mapValues(typography.lineHeights, String),
primaryColor: color.roles.primary.color,
primaryShade: color.primaryShade as MantinePrimaryShade,
radius: mapValues(radius.values, value => rem(value)),
respectReducedMotion: true,
shadows: mapValues(shadows.values, layers =>
layers
.map(
layer =>
`${rem(layer.offsetX)} ${rem(layer.offsetY)} ${rem(layer.blur)} ${rem(layer.spread)} ${rgba(color.base[layer.color as keyof typeof color.base], layer.opacity)}`,
)
.join(", "),
),
spacing: mapValues(spacing.values, value => rem(value)),
white: color.base.white,
});
const cssVariablesResolver: CSSVariablesResolver = resolvedTheme => ({
dark: {},
light: {
"--mantine-color-dimmed": getThemeColor(colorRoles.muted, resolvedTheme),
},
variables: Object.fromEntries(
Object.entries(colorRoles).map(([role, reference]) => [
`--wl-color-${role}`,
getThemeColor(reference, resolvedTheme),
]),
),
});
export { colorRoles, cssVariablesResolver, theme };
export { default as designTokens } from "@wealthledger/tokens/tokens.json";