Open floinay opened 2 days ago
@floinay I had the same issues while trying to figure out, eventually I understood part of the source code and created this lib to assist me https://github.com/maiconcarraro/use-material-you (react)
you can get some ideas looking the code, probably possible to create a convert to the old theme.
@floinay I had the same issues while trying to figure out, eventually I understood part of the source code and created this lib to assist me https://github.com/maiconcarraro/use-material-you (react)
you can get some ideas looking the code, probably possible to create a convert to the old theme.
Thanks a lot. I got some parts of code from your repository and some parts from this repository.
Maybe it can help for other dev to create dynamic customizable theme with angular material and color utilities:
import { argbFromHex, DynamicScheme as DS, Hct, Scheme, Theme, TonalPalette } from '@material/material-color-utilities';
import { ColorsSettings } from 'libraries/college-settings';
import { Variant } from '@material/material-color-utilities/dynamiccolor/variant';
import { DYNAMIC_SCHEME_FIELDS, DynamicSchemeProps } from './material-scheme';
type OnlyDynamicColors = keyof DynamicSchemeProps;
export type DynamicSchemeProps = {
primary: number;
onPrimary: number;
primaryContainer: number;
onPrimaryContainer: number;
secondary: number;
onSecondary: number;
secondaryContainer: number;
onSecondaryContainer: number;
tertiary: number;
onTertiary: number;
tertiaryContainer: number;
onTertiaryContainer: number;
error: number;
onError: number;
errorContainer: number;
onErrorContainer: number;
background: number;
onBackground: number;
surface: number;
onSurface: number;
surfaceVariant: number;
onSurfaceVariant: number;
outline: number;
outlineVariant: number;
shadow: number;
scrim: number;
inverseSurface: number;
inverseOnSurface: number;
inversePrimary: number;
};
export const DYNAMIC_SCHEME_FIELDS: Array<keyof DynamicSchemeProps> = [
'primary',
'onPrimary',
'primaryContainer',
'onPrimaryContainer',
'secondary',
'onSecondary',
'secondaryContainer',
'onSecondaryContainer',
'tertiary',
'onTertiary',
'tertiaryContainer',
'onTertiaryContainer',
'error',
'onError',
'errorContainer',
'onErrorContainer',
'background',
'onBackground',
'surface',
'onSurface',
'surfaceVariant',
'onSurfaceVariant',
'outline',
'outlineVariant',
'shadow',
'scrim',
'inverseSurface',
'inverseOnSurface',
'inversePrimary',
] satisfies OnlyDynamicColors[];
interface DynamicSchemeOptions {
sourceColorArgb: number;
variant: Variant;
contrastLevel: number;
isDark: boolean;
primaryPalette: TonalPalette;
secondaryPalette: TonalPalette;
tertiaryPalette: TonalPalette;
neutralPalette: TonalPalette;
neutralVariantPalette: TonalPalette;
}
class DynamicScheme extends DS {
private readonly props: DynamicSchemeProps;
constructor(args: DynamicSchemeOptions) {
super(args);
this.props = DYNAMIC_SCHEME_FIELDS.reduce((scheme, field) => {
scheme[field] = this[field];
return scheme;
}, {} as DynamicSchemeProps);
}
toJSON() {
return { ...this.props };
}
}
export function themeFromColorSettings(theme: ColorsSettings): Theme {
const source = argbFromHex(theme.colors_primary);
const hct = Hct.fromInt(argbFromHex(theme.colors_primary));
const hue = hct.hue;
const t = new DynamicScheme({
isDark: theme.is_dark_theme,
primaryPalette: TonalPalette.fromInt(argbFromHex(theme.colors_primary)),
secondaryPalette: TonalPalette.fromInt(argbFromHex(theme.colors_accent)),
tertiaryPalette: TonalPalette.fromHueAndChroma(hue + 60, 24),
neutralPalette: TonalPalette.fromHueAndChroma(hue, 4),
neutralVariantPalette: TonalPalette.fromHueAndChroma(hue, 8),
contrastLevel: 0,
sourceColorArgb: argbFromHex(theme.colors_primary),
variant: 5,
});
return {
source,
schemes: {
light: t as any as Scheme,
dark: t as any as Scheme,
},
palettes: {
primary: t.primaryPalette,
secondary: t.secondaryPalette,
tertiary: t.tertiaryPalette,
neutral: t.neutralPalette,
neutralVariant: t.neutralVariantPalette,
error: t.errorPalette,
},
customColors: [],
};
}
const theme = themeFromColorSettings(settings);
const targetElement = document.documentElement;
applyTheme(theme, {
target: targetElement,
brightnessSuffix: false,
});
I have noticed several parts of the TypeScript implementation still rely on deprecated methods like CorePalette, with suggestions to use DynamicScheme instead. However, there is no proper documentation, examples, or even clear code for how to fully generate themes using DynamicScheme in a manner similar to the existing theme utilities like applyTheme.
themeFromSourceColor
does not allow for customization of parameters.