Twin Macro

TailwindCSS and Material-UI(MUI) for a React Application.

Question: How do you combine the TailwindCSS theme with Material-UI in an Application? In other words, how do I make MUI theme work with TailwindCSS classes?

Answer: Twin Macro; I will be using a Vite React TypeScript Application to illustrate how to combine styling themes (TailwindCSS and Material-UI). This is very useful for large projects where you want to ensure there is synergy in styling themes and that patterns are reusable.

Definitions:
Twin Macro is a library that makes TailwindCSS able to work with other CSS-in-JS libraries such as styled-component, and Emotion. With this library, you have a wider range of styling capabilities.

TailwindCSS: is a styling library that uses utility first styling this means styling is done as class names. It’s a direct styling and handles mobile and web views. With TailwindCSS, there is no need for external CSS classes and Ids, you can build a complete custom design without ever leaving your HTML.

Material-UI: is a popular React UI library that offers different design components to create a user interface in applications. These components already exist and developers do not have to build them from scratch.

Vite: It’s just blazingly fast for Front-end development. See the article for the Vite setup. You can find Vite starter packages in Docs

Setup TailwindCSS
Installing TailwindCSS is very simple and direct. See Docs

  1. Run npx tailwindcss init -pto generate tailwind.config.js and postcss.config.js files. If your file is in commonjs(.cjs), you can rename it to .js and remove the type: “module” on the package.json file.
  2. Add the paths to files and configure your styling settings in the tailwind.config.js file. As shown below,
/** @type {import(‘tailwindcss’).Config} */
module.exports = {
mode: “jit”,
content: [“./src/**/*.{ts,tsx}”, “./components/**/*.{ts,tsx}”],
theme: {
extend: {
colors: {
primary: “hsla(120, 100% ,25%,1)”,
secondary: “hsla(330, 100% ,71%,1)”,
},
},
},
plugins: [],
};

4. Add the Tailwind directives to the App global CSS file. You could add this to your App.css file

//App.css

@tailwind base;
@tailwind components;
@tailwind utilities;

Setup Material-UI
1)
Install MUI libraries. See docs
yarn add @mui/material @emotion/react @emotion/styled
or
npm install @mui/material @emotion/react @emotion/styled

2) Create a theme.tsx file in the src folder and add the following,

// theme.tsx file
import { createTheme } from “@mui/material/styles”;
const theme = createTheme({});

export default theme;
// main.tsx
import React from “react”;
import ReactDOM from “react-dom/client”;
import App from “./App”;
import { ThemeProvider } from “@mui/material”;
import theme from “./theme”;

ReactDOM.createRoot(document.getElementById(“root”)
as HTMLElement).render(

<React.StrictMode>
<ThemeProvider theme={theme}>
<App />
</ThemeProvider>
</React.StrictMode>
);

Setup Twin Macro
1)
To Install the Twin Macro package, see the docs example also
yarn add twin.macroor npm install twin.macro

2) Install babel-plugins to support styling

yarn add babel-plugin-macros @emotion/babel-plugin-jsx-pragmatic @babel/plugin-transform-react-jsx -D
or
npm install babel-plugin-macros @emotion/babel-plugin-jsx-pragmatic @babel/plugin-transform-react-jsx -D

3) To the vite config.js file add the following,

// vite config.js

plugins: [
react({
babel: {
plugins: [
'babel-plugin-macros',
[
'@emotion/babel-plugin-jsx-pragmatic',
{
export: 'jsx',
import: '__cssprop',
module: '@emotion/react',
},
],
[
'@babel/plugin-transform-react-jsx',
{ pragma: '__cssprop' },
'twin.macro',
],
],
},
}),
],

4) And since we are using Typescript, we install a package to handle types in React.
yarn add @types/react -D or npm install @types/react -D

Also, create a file types/twin.d.ts in the root directory and add the following code :

import 'twin.macro'
import { css as cssImport } from '@emotion/react'
import styledImport from '@emotion/styled'
import { CSSInterpolation } from '@emotion/serialize'

declare module 'twin.macro' {
// The styled and css imports
const styled: typeof styledImport
const css: typeof cssImport
}

declare module 'react' {
// The tw and css prop
interface DOMAttributes<T> {
tw?: string
css?: CSSInterpolation
}
}

Using the TailwindCSS theme in MUI Theme
Now to extend the TailwindCSS theme to the MUI theme configuration using Twin macro, we import the tw and tailwindTheme modules from Twin Macro.
In the MUI theme.tsx file we use the tailwind theme(primary and secondary colors)and utility styling

/// theme.tsx

import { createTheme } from "@mui/material/styles";
import tw, { theme as tailwindTheme } from "twin.macro";

const theme = createTheme({
palette: {
primary: {
main: tailwindTheme`colors.primary`,
},
secondary: {
main: tailwindTheme`colors.secondary`,
},
},
components: {
MuiButton: {
styleOverrides: {
containedPrimary: {
...tw`bg-primary text-lg font-bold`,
color: tailwindTheme`colors.black`,
},
outlinedSecondary: {
backgroundColor: tailwindTheme`colors.secondary`,
color: tailwindTheme`colors.white`,
},
sizeLarge: {
height: "3.5rem",
...tw`px-8 text-base`,
},
},
},
},
});

export default theme;

Result:

With that, the MUI theme is in sync with the tailwind styling theme. You can go ahead to add more theme to your TailwindCSS and use it in your MUI Theme. Twin macro can also be used for direct styling on HTML elements too.

This starter pack can be found here

--

--

Software developer. Imaginative. I love to try,. I write to relearn while sharing the knowledge.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Sandygoodnews

Software developer. Imaginative. I love to try,. I write to relearn while sharing the knowledge.