material-foundation / material-color-utilities

Color libraries for Material You
Apache License 2.0
1.67k stars 144 forks source link

Is this project still maintained? #163

Open floinay opened 2 days ago

floinay commented 2 days ago

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.

  1. How i can use DynamicScheme for generation theme in typescript?
  2. The function themeFromSourceColor does not allow for customization of parameters. image
maiconcarraro commented 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 commented 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.

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,
});