material-foundation / material-color-utilities

Color libraries for Material You
Apache License 2.0
1.57k stars 134 forks source link

It can't export colorSurfaceContainer all colors in TypeScript #136

Closed Super12138 closed 6 months ago

Super12138 commented 6 months ago

I use this method to get theme:

const theme = themeFromSourceColor(argbFromHex('#f82506'));

console.log(JSON.stringify(theme, null, 2));

but it can't export colors in colorSurfaceContainer; I see the file https://github.com/material-foundation/material-color-utilities/blob/main/typescript/dynamiccolor/material_dynamic_colors.ts is support the new color, but how can I use it?

sxiong5 commented 6 months ago

I have the same issue, and it seems like there is already a PR (#127) to add the missing schema, but haven’t been merged, and the new version is not released yet. Therefore, the temporary solution is to create these schemas by yourself using the neutral.tone().

bre97-web commented 4 months ago

Actually it supports creating new colors, but use new SchemeContent(Hct.fromInt(argbFromHex(color)), isDark, contrastLevel) to create. You can refer to my code

image

// main.ts

import { generateMaterialThemeStyleText } from "./generate-material-theme";

console.log('== MATERIAL UTIL COLOR TESTING ==');
const styles = generateMaterialThemeStyleText('#ffffff', false, 0) as string
styles.split(';').forEach(e => console.log(e))
// generate-material-theme.ts

import { argbFromHex, MaterialDynamicColors, Hct, SchemeContent, hexFromArgb } from '@material/material-color-utilities'

const materialColors = {
    primaryPaletteKeyColor: MaterialDynamicColors.primaryPaletteKeyColor,
    secondaryPaletteKeyColor: MaterialDynamicColors.secondaryPaletteKeyColor,
    tertiaryPaletteKeyColor: MaterialDynamicColors.tertiaryPaletteKeyColor,
    neutralPaletteKeyColor: MaterialDynamicColors.neutralPaletteKeyColor,
    neutralVariantPaletteKeyColor: MaterialDynamicColors.neutralVariantPaletteKeyColor,
    background: MaterialDynamicColors.background,
    onBackground: MaterialDynamicColors.onBackground,
    surface: MaterialDynamicColors.surface,
    surfaceDim: MaterialDynamicColors.surfaceDim,
    surfaceBright: MaterialDynamicColors.surfaceBright,
    surfaceContainerLowest: MaterialDynamicColors.surfaceContainerLowest,
    surfaceContainerLow: MaterialDynamicColors.surfaceContainerLow,
    surfaceContainer: MaterialDynamicColors.surfaceContainer,
    surfaceContainerHigh: MaterialDynamicColors.surfaceContainerHigh,
    surfaceContainerHighest: MaterialDynamicColors.surfaceContainerHighest,
    onSurface: MaterialDynamicColors.onSurface,
    surfaceVariant: MaterialDynamicColors.surfaceVariant,
    onSurfaceVariant: MaterialDynamicColors.onSurfaceVariant,
    inverseSurface: MaterialDynamicColors.inverseSurface,
    inverseOnSurface: MaterialDynamicColors.inverseOnSurface,
    outline: MaterialDynamicColors.outline,
    outlineVariant: MaterialDynamicColors.outlineVariant,
    shadow: MaterialDynamicColors.shadow,
    scrim: MaterialDynamicColors.scrim,
    surfaceTint: MaterialDynamicColors.surfaceTint,
    primary: MaterialDynamicColors.primary,
    onPrimary: MaterialDynamicColors.onPrimary,
    primaryContainer: MaterialDynamicColors.primaryContainer,
    onPrimaryContainer: MaterialDynamicColors.onPrimaryContainer,
    inversePrimary: MaterialDynamicColors.inversePrimary,
    secondary: MaterialDynamicColors.secondary,
    onSecondary: MaterialDynamicColors.onSecondary,
    secondaryContainer: MaterialDynamicColors.secondaryContainer,
    onSecondaryContainer: MaterialDynamicColors.onSecondaryContainer,
    tertiary: MaterialDynamicColors.tertiary,
    onTertiary: MaterialDynamicColors.onTertiary,
    tertiaryContainer: MaterialDynamicColors.tertiaryContainer,
    onTertiaryContainer: MaterialDynamicColors.onTertiaryContainer,
    error: MaterialDynamicColors.error,
    onError: MaterialDynamicColors.onError,
    errorContainer: MaterialDynamicColors.errorContainer,
    onErrorContainer: MaterialDynamicColors.onErrorContainer,
    primaryFixed: MaterialDynamicColors.primaryFixed,
    primaryFixedDim: MaterialDynamicColors.primaryFixedDim,
    onPrimaryFixed: MaterialDynamicColors.onPrimaryFixed,
    onPrimaryFixedVariant: MaterialDynamicColors.onPrimaryFixedVariant,
    secondaryFixed: MaterialDynamicColors.secondaryFixed,
    secondaryFixedDim: MaterialDynamicColors.secondaryFixedDim,
    onSecondaryFixed: MaterialDynamicColors.onSecondaryFixed,
    onSecondaryFixedVariant: MaterialDynamicColors.onSecondaryFixedVariant,
    tertiaryFixed: MaterialDynamicColors.tertiaryFixed,
    tertiaryFixedDim: MaterialDynamicColors.tertiaryFixedDim,
    onTertiaryFixed: MaterialDynamicColors.onTertiaryFixed,
    onTertiaryFixedVariant: MaterialDynamicColors.onTertiaryFixedVariant,
}

export function generateMaterialThemeStyleText(
    sourceColor: string,
    dark = window.matchMedia('(prefers-color-scheme: dark)').matches,
    contrastLevel = 0
): string {
    const theme = createThemeFromSourceColor(sourceColor, dark, contrastLevel)
    return createStyleText(theme)
}

function createStyleText(theme: Record<string, any>): string {
    let styleString = ''
    for (const [k, v] of Object.entries(theme)) {
        styleString += `--md-sys-color-${k}: ${v};`
    }
    return styleString
}
function createThemeFromSourceColor(color: string, isDark: boolean, contrastLevel: number) {
    const scheme = new SchemeContent(Hct.fromInt(argbFromHex(color)), isDark, contrastLevel)

    const theme: Record<string, any> = {}

    for (const [key, value] of Object.entries(materialColors)) {
        /**
         * onSurface -> on-surface
         */
        theme[toKebabCase(key)] = hexFromArgb(value.getArgb(scheme))
    }

    return theme as typeof materialColors
}
function toKebabCase(str: string) {
    return str.split('').map((letter, idx) => {
        return letter.toUpperCase() === letter
            ? `${idx !== 0 ? '-' : ''}${letter.toLowerCase()}`
            : letter
    }).join('')
}