next.js 无法使用clsx和Tailwind以数据方式构建className

u2nhd7ah  于 2023-05-28  发布在  其他
关注(0)|答案(1)|浏览(163)

你好!这里不是熟练的Javascript开发人员,使用React和Next,更具体地说是this template
在声明组件类名时,我使用以下实用函数,它将tailwind-mergeclsx组合为suggested here

// utils.ts
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"

function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs))
}

为了使事情更简单,提高DRY甚至可读性,我希望能够在声明这些类名时动态插入顺风修饰符(例如dark:hover:md:...),如下所示:

// page.tsx
import { cn, dark, hover, md } from '@/utils'

<Component className={cn(
  "text-white text-sm",
  "w-full h-10",
  hover("font-bold text-lime-500"),
  md(
    "w-1/2 h-20",
    "text-xl"
  )
)}/>

为了实现这一点,我实现了一些其他实用程序函数:

// utils.ts
function apply_modifier(modifier: string, ...inputs: string[]) {
  return inputs.map((input) => `${modifier}:${input}`).join(" ")
}

function create_specialist_apply_modifier_function(modifier: string) {
  return (...inputs: string[]) => apply_modifier(modifier, ...inputs)
}

const dark = create_specialist_apply_modifier_function("dark")
const hover = create_specialist_apply_modifier_function("hover")
const md = create_specialist_apply_modifier_function("md")
...

我对它进行了测试,每次都得到了预期的字符串,但是,结果根本没有应用到组件,我不明白为什么
甚至以下内容也不起作用:

<Component className={clsx(
    ["text-2xl", "text-white"].map((c) => `dark:${c}`).join(" ")
)}/>

我很感激任何关于理解这个问题的想法,也想一个替代的解决方案

  • 奥布里加多 *
q7solyqu

q7solyqu1#

根据文件:
Tailwind如何提取类名的最重要的含义是,它只会在源文件中找到作为完整的未断开字符串存在的类。
如果你使用字符串插值或将部分类名连接在一起,Tailwind将找不到它们,因此不会生成相应的CSS:

不要动态构造类名

<div class="text-{{ error ? 'red' : 'green' }}-600"></div>

在上面的例子中,字符串text-red-600text-green-600不存在,所以Tailwind不会生成这些类。
相反,请确保您使用的任何类名都完整存在:

始终使用完整的类名

<div class="{{ error ? 'text-red-600' : 'text-green-600' }}"></div>

最直接的解决方案是使用完整的类名:

<Component className={cn(
  "text-white text-sm",
  "w-full h-10",
  "hover:font-bold hover:text-lime-500",
  "md:w-1/2 md:h-20",
  "md:text-xl"
)}/>

或者,您可以生成安全列表类,但这将变得无法快速维护,并且您必须在模板和Tailwind配置之间进行大量上下文切换。
如果您真的希望您的函数工作,您可以在Tailwind类提取之前转换内容文件,这样转换器就可以将函数调用转换为完整的类名。注意,这只会转换Tailwind扫描的字符串内容,不会影响项目中的可操作代码:

<Component className={cn(
  "text-white text-sm",
  "w-full h-10",
  hover("font-bold text-lime-500"),
  md(
    "w-1/2 h-20",
    "text-xl"
  )
)}/>

// After some trickery, perhaps something like ↓

<Component className={cn(
  "text-white text-sm",
  "w-full h-10",
  hover("hover:font-bold hover:text-lime-500"),
  md(
    "md:w-1/2 md:h-20",
    "md:text-xl"
  )
)}/>

相关问题