Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
utils.theme.ts Maven / Gradle / Ivy
import { LocaleConfig } from 'contexts/LocaleContext';
import merge from 'deepmerge';
import globalTheme from 'theme/theme';
import {
GearsTheme, GearsThemeConfig, GearsThemeKey, GearsThemeVariables, PartialGearsMuiTheme,
ThemeIcons
} from 'types/theming';
import Types from 'types/types';
import { createTheme, darken, GearsMuiTheme, lighten, Theme } from '@mui/material';
import { Runtime } from '../helpers/runtime';
import xlritTheme from '../themes/xlrit.json';
const localThemes = loadThemes()
class ThemeBuilder {
themes: GearsTheme[]
locale: LocaleConfig
config: GearsThemeConfig | undefined
constructor(locale: LocaleConfig, themeConfig: GearsThemeConfig | undefined) {
this.themes = []
this.locale = locale
this.config = themeConfig
}
createThemes(): ThemeBuilder {
this.themes = [...(this.config?.themes || []), ...localThemes]
return this
}
addIcons(): ThemeBuilder {
this.themes = this.themes.map((theme: GearsTheme) => {
const themeIcons = theme.icons || {}
const globalIcons = this.config?.icons || {}
const icons = merge.all([globalIcons, themeIcons]) as ThemeIcons
if (Object.keys(icons).length > 0)
return { ...theme, icons: icons }
else
return theme
})
return this
}
addStyling(): ThemeBuilder {
this.themes = toMuiThemes(this.locale, this.themes)
return this
}
getThemes(): GearsTheme[] {
return this.themes
}
};
export function createCustomThemes(locale: LocaleConfig, themeConfig: GearsThemeConfig | undefined): GearsTheme[] {
return (new ThemeBuilder(locale, themeConfig))
.createThemes()
.addIcons()
.addStyling()
.getThemes()
}
function toMuiThemes(locale: LocaleConfig, themes: GearsTheme[]): GearsTheme[] {
const defaultTheme = createDefaultTheme(locale)
return themes.map(theme => {
const logoTheme = toMuiLogoTheme(theme)
const variables = theme?.variables || {}
const userTheme = toResolvedUserTheme(theme.theme, variables)
const colorTheme = toColorTheme(defaultTheme, userTheme)
const headingTheme = toHeadingTheme(colorTheme, userTheme)
const muiTheme = merge.all([defaultTheme, colorTheme, headingTheme, userTheme, logoTheme]) as GearsMuiTheme
return {
...theme,
theme: muiTheme
}
})
}
export function createDefaultTheme(locale: LocaleConfig): GearsMuiTheme {
const theme = toLocalizedMuiTheme(globalTheme, locale)
const amendment = {
palette: {
contrast: theme.palette.grey[100],
background: {
default: "#ffffff",
}
},
components: {
title: {
fontWeight: 'bold',
fontStyle: 'italic',
fontSize: 28
},
banner : {
backgroundColor : theme.palette.primary.main,
color : "#ffffff",
elevation: 15,
height: "48px"
},
toolbar : {
paddingRight: "24px",
height: "48px !important",
minHeight: "0 !important"
},
sidebar: {
width: "256px",
//background: "#f1f1f1"
backgroundColor: "#fbfafd"
},
badge : {
color : theme.palette.secondary.main,
backgroundColor : theme.palette.secondary.light
},
logo: {},
heading : {
color: "#203e60"
}
}
}
return merge.all([theme, amendment]) as GearsMuiTheme
}
export const toLocalizedMuiTheme = (theme: Theme, locale: LocaleConfig): Theme => {
// @ts-ignore
return createTheme(theme, locale.muiLocale)
}
export function isGearsThemes(themes: any) {
return themes && Types.isObject(themes) &&
themes.hasOwnProperty('themes') &&
Array.isArray(themes.themes)
}
export function isGearsTheme(theme: any) {
return theme && Types.isObject(theme) &&
theme.hasOwnProperty('theme') &&
theme.hasOwnProperty('key') &&
theme.hasOwnProperty('label') &&
theme.hasOwnProperty('logo')
}
function toMuiLogoTheme(theme: GearsTheme) {
const adjustSrc = (src: string | undefined,filename: string | undefined) => src ? src : filename ? Runtime.logo(filename) : undefined
const logoSmall = theme?.logoSmall
? { logoSmall: {
...theme?.logoSmall,
src: adjustSrc(theme?.logoSmall?.src, theme?.logoSmall?.filename)
}
}
: undefined
const logo = { logo: {
...theme?.logo,
src: adjustSrc(theme?.logo?.src, theme?.logo?.filename)
}
}
if (!logo.logo.src)
console.error("No logo url provided for theme: %o", theme?.key)
return {
"components": {
...logo,
...logoSmall
}
}
}
// a resolver for when variables are used in the theme, with the format: $variable_name
function toResolvedUserTheme(theme: PartialGearsMuiTheme, variables: GearsThemeVariables): PartialGearsMuiTheme {
function resolve(value: any): any {
switch (true) {
case Types.isObject(value):
const entries = Object.entries(value as any)
.map(([key, value]) => [key, resolve(value)])
return Object.fromEntries(entries)
case typeof value == "string" && value.startsWith("$"):
const variable = value.substring(1)
if (variables.hasOwnProperty(variable))
return variables[variable]
else {
console.error("Could not resolve theme variable: %o", variable)
return value
}
case Array.isArray(value):
return value.map((value: any) => resolve(value))
default:
return value
}
}
return resolve(theme)
}
function toHeadingTheme(colorTheme: PartialGearsMuiTheme, userTheme: PartialGearsMuiTheme): PartialGearsMuiTheme {
const primary = colorTheme?.palette?.primary
const defaultHeadingColor = primary?.dark || "black"
const defaultHeadingTheme = {
components: {
heading: {
color: defaultHeadingColor
}
}
}
const userHeadingTheme = {
components: {
heading: userTheme.components?.heading || {}
}
}
const headingTheme = merge.all([defaultHeadingTheme, userHeadingTheme]) as GearsMuiTheme
const headingStyle = headingTheme.components.heading
return {
...headingTheme,
typography: {
h1: headingStyle,
h2: headingStyle,
h3: headingStyle,
h4: headingStyle,
h5: headingStyle,
h6: headingStyle
}
}
}
// This results in the primary and secondary color palettes, in an MUI theme structure
function toColorTheme(defaultTheme: GearsMuiTheme, userTheme: PartialGearsMuiTheme): PartialGearsMuiTheme {
return merge.all([
toPaletteColorTheme(defaultTheme, userTheme, 'primary'),
toPaletteColorTheme(defaultTheme, userTheme, 'secondary'),
])
}
// This results in a Mui theme color palette, where it's type is 'primary' or 'secondary'
function toPaletteColorTheme(defaultTheme: GearsMuiTheme, theme: PartialGearsMuiTheme, attribute: string): PartialGearsMuiTheme {
// @ts-ignore
const getColor = (theme: PartialGearsMuiTheme) => theme?.palette?.[attribute]?.main || theme?.components?.[attribute]
// @ts-ignore
const hasColor = (theme: PartialGearsMuiTheme) => !!theme?.palette?.[attribute]?.main
if (hasColor(theme)) {
const color = getColor(theme)
const defaultColor = {
palette: {
[attribute]: {
light: lighten(color, 0.7),
main: color,
dark: darken(color, 0.7)
}
}
}
const userColor = {
palette: {
// @ts-ignore
[attribute]: theme?.palette?.[attribute] || {}
}
}
return merge.all([defaultColor, userColor])
} else {
return {
palette: {
// @ts-ignore
[attribute]: defaultTheme.palette[attribute]
}
}
}
}
export function selectThemeKey(themes: GearsTheme[], themeKey: GearsThemeKey, gearsTheme: GearsThemeConfig): string {
if (hasTheme(themes, themeKey))
return themeKey
return 'default'
}
export function hasTheme(themes: GearsTheme[], key: GearsThemeKey) {
return key && themes.some(theme => theme.key == key)
}
export function selectTheme(themes: GearsTheme[], key: GearsThemeKey): GearsTheme {
if (!Array.isArray(themes) || themes.length == 0)
throw new Error("Could not load any theme")
const theme = themes.find(theme => theme.key == key)
if (!theme)
throw new Error("Could not load theme: " + key)
return theme
}
function loadThemes() {
//const requireContext = require.context('../themes', false, /\.json$/);
//const themes = [];
//requireContext.keys().forEach((key) => {
// const obj = requireContext(key);
// themes.push(obj)
//});
//return themes;
return [xlritTheme]
}
export const checkboxCellStyle = {
width: "1%",
padding: 0,
paddingLeft: "6px"
}