Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Alert] Filled variant text color should be using theme.palette[color].contrastText and not theme.palette.getContrastText #33512

Open
2 tasks done
povilass opened this issue Jul 14, 2022 · 8 comments
Labels
component: alert This is the name of the generic UI component, not the React module! docs Improvements or additions to the documentation

Comments

@povilass
Copy link
Contributor

povilass commented Jul 14, 2022

Duplicates

  • I have searched the existing issues

Latest version

  • I have tested the latest version

Current behavior 😯

Currenly theme.palette.getContrastText is used to calculate text color.

Expected behavior 🤔

Expected color to be provided from theme.palette[color].contrastText

image

Steps to reproduce 🕹

https://codesandbox.io/s/clever-almeida-u36ek8?file=/src/App.tsx

Context 🔦

Pull request broke Alert #29813 text colour. If contrastText is provided it should not calculate theme.palette.getContrastText or should account on provided contrastText

Your environment 🌎

No response

@povilass povilass added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Jul 14, 2022
@mnajdova
Copy link
Member

Thanks for the report. #29813 did change the behavior, but it was for solving an issue. The contrast color in the cases where the colors changed is because the black gives better contrast than the white color for the text. We could use contrastText for light mode, but that won't work for dark mode, mainly because we use the color.palette[color].dark as a background, and the color.palette[color].contrastText is meant as a contrast text for the main color:

index 5cfcd0492e..6ce845f83e 100644
--- a/packages/mui-material/src/Alert/Alert.js
+++ b/packages/mui-material/src/Alert/Alert.js
@@ -95,11 +95,14 @@ const AlertRoot = styled(Paper, {
                 theme.palette.mode === 'dark'
                   ? theme.palette[color].dark
                   : theme.palette[color].main,
-              color: theme.palette.getContrastText(
-                theme.palette.mode === 'dark'
-                  ? theme.palette[color].dark
-                  : theme.palette[color].main,
-              ),
+              color:
+                theme.palette.mode === 'light' && theme.palette[color].contrastText
+                  ? theme.palette[color].contrastText
+                  : theme.palette.getContrastText(
+                      theme.palette.mode === 'dark'
+                        ? theme.palette[color].dark
+                        : theme.palette[color].main,
+                    ),
             }),
       }),
   };

@siriwatknp what do you think about this change?

@mnajdova mnajdova added new feature New feature or request component: alert This is the name of the generic UI component, not the React module! and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer new feature New feature or request labels Jul 15, 2022
@povilass
Copy link
Contributor Author

povilass commented Jul 15, 2022

So the problem maybe is that theme.palette[color].contrastText only with theme.palette[color].main.
Kinda sticky situation because theme.palette[color].light need to have theme.palette[color].lightContrastText and theme.palette[color].dark need to have theme.palette[color].darkContrastText. Problem maybe can be solve if each color would have it's own contrastText color and it would be already resolve in createPalette function also it can be overriden by what actual color you passed.

{
  light?: string;
  main: string;
  dark?: string;
  contrastText?: string;
  lightContrastText?: string;
  darkContrastText?: string;
}

It would leave you with

{

function resolveContrastColor(color: any, theme: any) {
     const isLightMode = theme.palette.mode === 'light';
     const contrastText = isLightMode? theme.palette[color].contrastText ? theme.palette[color].darkContrastText;
     return contrastText ?? theme.palette.getContrastText(isLightMode? theme.palette[color].main: theme.palette[color].dark,)
}

color: resolveContrastColor(color, theme)
}

Or this should be resolve in theme palette after createPalette

{
success: {
            main: '#00C796',
            dark: '#008B69',
            light: '#33D2AB',
            contrastText: paletteMode === 'light' ? '#fff' : getContrastText('#008B69'),
        },
}

And you only left with

+     color: theme.palette[color].contrastText
+                  ? theme.palette[color].contrastText
+                  : theme.palette.getContrastText(
+                      theme.palette.mode === 'dark'
+                        ? theme.palette[color].dark
+                        : theme.palette[color].main,
+                    ),

@mnajdova
Copy link
Member

We haven't had so far the need to have a contrast text color for each color in the palette, so I wouldn't add it until we see this required in more than one place. I feel this would be overengineering for the problem we have.

For the extendTheme util that is based on CSS variables, maybe we can create automatically contrast text for each color if we see the need for it.

Let's also consider what @siriwatknp thinks.

@siriwatknp
Copy link
Member

I won't do anything at this point because the contrast ratio is expected (it should be black):

Screen Shot 2565-07-18 at 13 38 15

Screen Shot 2565-07-18 at 13 38 37

What we could do is add a comment to the Alert page that the filled variant calculates color from the default background and provide an example of how to change the behavior:

const theme = createTheme({
  components: {
    MuiAlert: {
      styleOverrides: {
        root: ({ ownerState }) => ({
          ...(ownerState.variant === "filled" && {
            color: "#fff"
          })
        })
      }
    }
  }
});

Here: https://codesandbox.io/s/admiring-shape-rzm6lw?file=/src/App.tsx:341-884

@siriwatknp siriwatknp added the docs Improvements or additions to the documentation label Jul 18, 2022
@povilass
Copy link
Contributor Author

povilass commented Jul 19, 2022

@siriwatknp @mnajdova I agreed not to do anything. But do we need extra logic in components on how to resolve contrastColor if it already is calculated in the palette itself

color.contrastText = getContrastText(color.main);
. Maybe we need only calculate dark color also and just use it as it is theme.palette.mode === 'light' ? theme.palette[color].contrastText : theme.palette[color].darkContrastText which pobably can decrease bundle size also at some components.

Right now I see only code duplication for no reason in each component with contrast text colours and the same logic all over the place.

The other option is to remove contrastText form theme and changed it to getModeContrastText and use it in all places also. You do not need 2 ways on how colour should be resolved.

@mnajdova
Copy link
Member

Thanks @povilass this is a good point. We are likely going to hit this in the future with CSS vars. @povilass currently we don't need this in other components, this is why I don't think we should add it right now. cc @siriwatknp did you need so far something like this for joy?

@richcatt
Copy link

Apologies if this is the wrong place to ask the question, but does this mean that the example in the docs is no longer supported - is the contrast text always either white or black now? And does the contrastText property have no effect when using a custom theme?

https://mui.com/material-ui/react-alert/
image

@richcatt
Copy link

Sorry, ignore me - I've realised the above example is achievable by not using the filled variant.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: alert This is the name of the generic UI component, not the React module! docs Improvements or additions to the documentation
Projects
None yet
Development

No branches or pull requests

4 participants