Home > Back-end >  MUI-Theming with Tailwind in className
MUI-Theming with Tailwind in className

Time:01-17

I want to use MUI theming in my otherwise Tailwind-styled page so I can centrally handle the color palettes for dark and light mode since I found the decentral dark and light mode theming provided by Tailwind not very practicable in case I want to change colors.

My approach is to use the Tailwind syntax for arbitrary values and pass the hex code from the theme.js color palette.

the Tailwind arbitrary syntax is:

bg-[#hex] 

e.g.:

bg-[#50d71e]

which just works fine in normal classNames, e.g.:

    <div className={`bg-[#50d71e]`}>
    <div/>

gives me a green background (#50d71e) in that container.

On the other side, I have a mui-themed template page. Here I can reference colors as follows:

import {useTheme} from "@mui/material";
import { tokens } from "../../theme";

const AnyName = () => {
  const theme = useTheme();
  const colors = tokens(theme.palette.mode);

return (
<Box backgroundColor={colors.grey[400]}></Box>
<Box sx={{backgroundColor: colors.grey[500],}}></Box>
}
export default AnyName;

And again, it just works fine.

Now, if I want to fuse these two approaches, I am struggling to query the hex code out of the const colors = tokens(theme.palette.mode);.

The theme.js holds all color values as hex, so I think this should be possible. Here is a look inside:

export const tokens = (mode) => ({
    ...(mode === 'dark'
        ? 
        {
            grey: {
                900: "#141414",
                800: "#292929",
                700: "#3d3d3d",
                600: "#525252",
                500: "#666666",
                400: "#858585",
                300: "#a3a3a3",
                200: "#c2c2c2",
                100: "#e0e0e0",
            },
        } : {
            grey: {
                100: "#141414",
                200: "#292929",
                300: "#3d3d3d",
                400: "#525252",
                500: "#666666",
                600: "#858585",
                700: "#a3a3a3",
                800: "#c2c2c2",
                900: "#e0e0e0",
            },
         }),
      });

** What I have tried: **

const AnyName = ({ anyProp }) => {
  const theme = useTheme();
  const colors = tokens(theme.palette.mode);

  return (
    <div
      className={`bg-[${colors.grey[400]}]`}
    ></div>
  );
};
export default AnyName;

This doesn't work. I guess it is a matter of scoping, but I am not sure, and I honestly do not know what I am doing. So I tried a few more things like:

className={`bg-[{colors.grey[400]}]`}

Which doesn't seem to reference colors at all. And:

className={`bg-[colors.grey[400]]`}

Which also does not reference colors. All three approaches result in a transparent background.

Now I am here, hoping for your help. Thanks.

CodePudding user response:

I suspect this to work, But you are not able to see the background color because the there is no children for this div, which makes it height of 0

Try adding height:

 <div className={`bg-[${colors.grey[400]}] h-24`}/>

CodePudding user response:

Thanks for your answer. Up there is not the complete code. I tried to keep it short for the post. There are children, and if I set the background using normal Tailwind syntax, e.g., bg-[#50d71e], it works as expected. Here is the full return statement, unmodified:

return (
    <div
      className={`bg-[#50d71e] shadow-lg rounded-lg p-0 lg:p-8 pb-12 mb-8`}
    >
      <div className="relative overflow-hidden shadow-md pb-80 mb-6">
        <img
          src={post.featuredImage.url}
          alt={post.title}
          className="object-top absolute h-80 w-full object-cover shadow-lg rounded-t-lg lg:rounded-lg"
        />
      </div>
      <h1
        className="transition duration-700 text-center mb-8 cursor-pointer
        hover:[text-cyan-400] text-3xl font-semibold"
      >
        <Link href={`/post/${post.slug}`}>{post.title}</Link>
      </h1>
      <div className="block lg:flex text-center items-center justify-center mb-8 w-full">
        <div className="flex items-center justify-center mb-4 lg:mb-0 w-full lg:w-auto mr-8">
          <img
            alt={post.author.name}
            height="30px"
            width="30px"
            className="align-middle rounded-full"
            src={post.author.photo.url}
          />
          <p className="inline align-middle text-gray-700 ml-2 text-lg">
            {post.author.name}
          </p>
        </div>
        <div className="font-medium text-gray-700">
          <svg
            xmlns="http://www.w3.org/2000/svg"
            className="h-6 w-6 inline mr-2 text-cyan-600"
            fill="none"
            viewBox="0 0 24 24"
            stroke="currentColor"
          >
            <path
              strokeLinecap="round"
              strokeLinejoin="round"
              strokeWidth="2"
              d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"
            />
          </svg>
          <span>{moment(post.createAt).format("DD. MMM, YYYY")}</span>
        </div>
      </div>
      <p className="text-center text-lg text-gray-700 font-normal px-4 lg:px-20 mb-8">
        {post.excerpt}
      </p>
      <div className="text-center">
        <Link href={`/post/${post.slug}`}>
          <span className="transition duration-500 transform hover:-translate-y-1 inline-block bg-cyan-500 text-lg font-medium rounded-full text-white px-8 py-3 cursor-pointer">
            Continue Reading
          </span>
        </Link>
      </div>
    </div>
  );

Since the VS Code autocompletion works as intended when using the $-approach, I guess maybe it is not or not only a matter of scope.

  • Related