Skip to content

Custom classes with media queries are stripped away #2388

@Zdend

Description

@Zdend

Describe the Bug

When defining a custom class using addUtilities plugin function, and this class being a combination of multiple classes including variants such as dark: or breakpoint variant such as sm:, it will inline classes that aren't wrapped inside a media query and ignore the rest.

Tailwind config

darkMode: 'media',
plugins: [
  plugin(function ({ addUtilities }) {
    addUtilities({
      '.text-body': {
        '@apply text-[green] dark:text-[orange]': {},
      },
    });
  }),
],

Used inside a component

<Text className="text-body">
  This text should be green in the light mode and orange in the dark mode
</Text>

HTML Result

<p style="color:rgb(0,128,0);font-size:14px;line-height:24px;margin-top:16px;margin-bottom:16px">
  This text should be green in light mode and orange in dark mode
</p>

This isn't an issue if I use those classes inline like below, however, I am trying to build a design system that uses certain design tokens consistently and so I don't want to always define dark mode variant everywhere.

<Text className="text-[green] dark:text-[orange]">
  This text should be green in light mode and orange in dark mode
</Text>
<p class="dark_text-orange" style="color:rgb(0,128,0);font-size:14px;line-height:24px;margin-top:16px;margin-bottom:16px">
  This text should be green in light mode and orange in dark mode
</p>

Which package is affected (leave empty if unsure)

@react-email/tailwind

Link to the code that reproduces this issue

N/A

To Reproduce

Create a simple template and observe the result inside the preview

import { Body, Head, Html, Text, Tailwind } from '@react-email/components';
import plugin from 'tailwindcss/plugin';

const Foo = () => {
  return (
    <Tailwind
      config={{
        darkMode: 'media',
        plugins: [
          plugin(function ({ addUtilities }) {
            addUtilities({
              '.text-body': {
                '@apply text-[green] dark:text-[orange]': {},
              },
            });
          }),
        ],
      }}
    >
      <Html>
        <Head />
        <Body>
          <Text className="text-body">
            This text should be green in light mode and orange in dark mode
          </Text>
        </Body>
      </Html>
    </Tailwind>
  );
};

export default Foo;
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html dir="ltr" lang="en">
  <head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
    <meta name="x-apple-disable-message-reformatting" />
    <style>
      @media(prefers-color-scheme:dark){.text-body{color:rgb(255,165,0) !important}}
    </style>
  </head>
  <body>
    <!--$-->
    <p
      style="color:rgb(0,128,0);font-size:14px;line-height:24px;margin-top:16px;margin-bottom:16px">
      This text should be green in light mode and orange in dark mode
    </p>
    <!--7--><!--/$-->
  </body>
</html>

Version:
react-email: 4.2.4

Expected Behavior

Given that text-body still has some classes that couldn't be inlined, I expect the class to be preserved in the HTML

Expected HTML result

<p class="text-body" style="color:rgb(0,128,0);font-size:14px;line-height:24px;margin-top:16px;margin-bottom:16px">
  This text should be green in light mode and orange in dark mode
</p>

What's your node version? (if relevant)

22

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions