material-ui icon indicating copy to clipboard operation
material-ui copied to clipboard

Add support for CSS `color-mix()` in theme palette

Open chimericdream opened this issue 2 years ago • 4 comments

Summary 💡

I wanted to use CSS's color-mix function for my theme palette colors to simplify the process of creating all of the main/light/dark variants. However, it appears that the decomposeColor function doesn't yet support this.

Examples 🌈

const DARKEN_PERCENT = 33;
const LIGHTEN_PERCENT = 33;

const makeColor = (color: string, contrast: string) => ({
    main: color,
    light: `color-mix(in hsl, ${color} ${LIGHTEN_PERCENT}%, #fff)`,
    dark: `color-mix(in hsl, ${color} ${DARKEN_PERCENT}%, #000)`,
    contrastText: contrast,
});

export const theme = createTheme({
    palette: {
        mode: 'dark',
        primary: makeColor(..., '#fff'),
        secondary: makeColor(..., '#000'),
        error: makeColor(..., '#000'),
        warning: makeColor(..., '#000'),
        info: makeColor(..., '#000'),
        success: makeColor(..., '#fff'),
    },
    ...
});

Motivation 🔦

Allowing us to use the native color-mix CSS function simplifies the creation of new themes.

chimericdream avatar Dec 05 '23 08:12 chimericdream

Good point!

siriwatknp avatar Dec 06 '23 01:12 siriwatknp

Hello, may I take this?

JorensM avatar Dec 10 '23 17:12 JorensM

@chimericdream I wouldn't mind taking this on since I've been working on another PR to fix some color functions. Out of curiosity though, wouldn't MUI's darken and lighten helpers work for this use case?

import { darken, lighten } from '@mui/system';

const DARKEN_PERCENT = 33;
const LIGHTEN_PERCENT = 33;

const makeColor = (color: string, contrast: string) => ({
    main: color,
    light: lighten(color, LIGHTEN_PERCENT / 100),
    dark: darken(color, DARKEN_PERCENT / 100),
    contrastText: contrast,
});

arronhunt avatar Jul 03 '24 19:07 arronhunt

@arronhunt they probably would, at least for my example above. However, it still wouldn't be possible to blend arbitrary colors, which is where color-mix can get really powerful.

chimericdream avatar Jul 03 '24 21:07 chimericdream

@chimericdream Check this out! https://stackblitz.com/edit/9gzfgfql?file=src%2FDemo.tsx

It's currently a WIP PR: https://github.com/mui/material-ui/pull/43942/, you can participate by giving it a like to pushing to the finishing line.

const DARKEN_PERCENT = 33;
const LIGHTEN_PERCENT = 33;

const makeColor = (color: string, contrast: string) => ({
  main: color,
  light: `color-mix(in hsl, ${color} ${LIGHTEN_PERCENT}%, #fff)`,
  dark: `color-mix(in hsl, ${color} ${DARKEN_PERCENT}%, #000)`,
  contrastText: contrast,
});

const theme = createTheme({
  cssVariables: {
    nativeColorSyntax: true, // ⚡️ new feature!
  },
  palette: {
    primary: makeColor('red', '#fff'),
    info: {
      main: 'oklch(0.7 0.1 81)',
    },
  },
});

siriwatknp avatar Jul 10 '25 07:07 siriwatknp

This issue has been closed. If you have a similar problem but not exactly the same, please open a new issue. Now, if you have additional information related to this issue or things that could help future readers, feel free to leave a comment.

github-actions[bot] avatar Aug 04 '25 02:08 github-actions[bot]