在TailwinCss中动态构建类名

qvtsj1bj  于 2022-10-21  发布在  其他
关注(0)|答案(7)|浏览(135)

我目前正在使用TailwinCss为我的下一个项目构建组件库,我只是在处理Button组件时遇到了一个小问题。
我传入了一个道具,如'primary''secondary',它与我在tailwind.config.js中指定的颜色相匹配,然后我想使用Template literals将其分配给按钮组件,如下所示:bg-${color}-500

<button
    className={`
    w-40 rounded-lg p-3 m-2 font-bold transition-all duration-100 border-2 active:scale-[0.98]
    bg-${color}-500 `}
    onClick={onClick}
    type="button"
    tabIndex={0}
  >
    {children}
</button>

类名在浏览器中显示得很好,它在DOM中显示bg-primary-500,但不在应用的样式选项卡中显示。

主题配置如下:

theme: {
    extend: {
      colors: {
        primary: {
          500: '#B76B3F',
        },
        secondary: {
          500: '#344055',
        },
      },
    },
  },

但它不会应用任何造型。如果我只是手动添加bg-primary-500,它工作得很好。
老实说,我只是想知道这是因为JIT编译器没有选择动态类名,还是我做错了什么(或者这不是使用顺风的方式)。
欢迎任何帮助,提前谢谢!

ltskdhd1

ltskdhd11#

所以,在发现这种工作方式不被推荐,JIT也不支持它之后(感谢慷慨的评论者)。我已经将方法更改为更基于“配置”的方法。
基本上,我使用不同道具的基本配置定义常量,并将这些配置应用于组件。这需要更多的维护工作,但它可以做到这一点。
以下是配置的示例。(目前没有打字)和一些更好的重构,但你会有想法的。

const buttonConfig = {
  // Colors
  primary: {
    bgColor: 'bg-primary-500',
    color: 'text-white',
    outline:
      'border-primary-500 text-primary-500 bg-opacity-0 hover:bg-opacity-10',
  },
  secondary: {
    bgColor: 'bg-secondary-500',
    color: 'text-white',
    outline:
      'border-secondary-500 text-secondary-500 bg-opacity-0 hover:bg-opacity-10',
  },

  // Sizes
  small: 'px-3 py-2',
  medium: 'px-4 py-2',
  large: 'px-5 py-2',
};

然后,我只需像这样应用样式:

<motion.button
    whileTap={{ scale: 0.98 }}
    className={`
    rounded-lg font-bold transition-all duration-100 border-2 focus:outline-none
    ${buttonConfig[size]}
    ${outlined && buttonConfig[color].outline}
    ${buttonConfig[color].bgColor} ${buttonConfig[color].color}`}
    onClick={onClick}
    type="button"
    tabIndex={0}
  >
    {children}
  </motion.button>
6yjfywim

6yjfywim2#

不推荐使用这种编写TailWind CSS类的方式。甚至JIT模式也不支持它,引用TailWind CSS文档的话说:“TailWind不包括任何类型的客户端运行时,因此类名需要在构建时是静态可提取的,并且不能依赖于任何类型的在客户端改变的任意动态值

7rtdyuoh

7rtdyuoh3#

正如有人在这个帖子中所说的,TailWindCSS3不支持动态类名(请参阅https://tailwindcss.com/docs/content-configuration#dynamic-class-names).
我使用**“安全列表”**功能从清除中排除了一些类名。在trawind.config.js中,您可以使用纯JS来开发如下所示的内容:(我同意这有点老套)

const colors = require('./node_modules/tailwindcss/colors');
const colorSaveList = [];
const extendeColors = {};

for (const key in colors) {
  extendeColors[key] = colors[key];

  // To avoid tailWind "Color deprecated" warning
  if (!['lightBlue', 'warmGray', 'trueGray', 'coolGray',  'blueGray'].includes(key))
  {
    colorSaveList.push(`text-${key}-${colorValue}`);
    colorSaveList.push(`bg-${key}-${colorValue}`);
  }
}

module.exports = {
  content: [
    "./index.html",
    "./src/**/*.{vue,js,ts,jsx,tsx}"
  ],
  safelist: colorSaveList,
  theme: {
   extend: {
      colors: extendeColors
   }
  },
  plugins: [
    require('tailwind-scrollbar'),
  ]

}

编辑:更好的实施-https://stackoverflow.com/a/73057959/11614995

rdlzhqv9

rdlzhqv94#

如果有人在2022年遇到--我接受了A.Mrózek的回答,做了几个调整,以避免不建议使用的警告和迭代非对象调色板的问题。

const tailwindColors = require("./node_modules/tailwindcss/colors")
const colorSafeList = []

// Skip these to avoid a load of deprecated warnings when tailwind starts up
const deprecated = ["lightBlue", "warmGray", "trueGray", "coolGray", "blueGray"]

for (const colorName in tailwindColors) {
  if (deprecated.includes(colorName)) {
    continue
  }

  const shades = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900]

  const pallette = tailwindColors[colorName]

  if (typeof pallette === "object") {
    shades.forEach((shade) => {
      if (shade in pallette) {
        colorSafeList.push(`text-${colorName}-${shade}`)
        colorSafeList.push(`bg-${colorName}-${shade}`)
      }
    })
  }
}

// tailwind.config.js
module.exports = {
  safelist: colorSafeList,
  content: ["{pages,app}/**/*.{js,ts,jsx,tsx}"],
  theme: {
    extend: {
      colors: tailwindColors,
    },
  },
  plugins: [],
}
iqjalb3h

iqjalb3h5#

对于顺风JIT模式或使用JIT的v3,必须确保导出对象样式的文件包含在tailwind.config.js的内容选项中,例如

content: ["./src/styles/**/*.{html,js}"],
0ejtzxu1

0ejtzxu16#

在v3中,正如Bless所说,您可以更改内容数组以支持这一点。
我有这个

const PokemonTypeMap = {
  ghost: {
    classes: "bg-purple-900 text-white",
    text: "fantasma",
  },
  normal: {
    classes: "bg-gray-500 text-white",
    text: "normal",
  },
  dark: {
    classes: "bg-black text-white",
    text: "siniestro",
  },
  psychic: {
    classes: "bg-[#fc46aa] text-white",
    text: "psíquico",
  },
};

function PokemonType(props) {
  const pokemonType = PokemonTypeMap[props.type];

  return (
    <span
      className={pokemonType.classes + " p-1 px-3 rounded-3xl leading-6 lowercase text-sm font-['Open_Sans'] italic"}
    >
      {pokemonType.text}
    </span>
  );
}

export default PokemonType;

类似于您的方法,然后我将数组移动到一个JSON文件,它认为工作正常,但浏览器缓存...因此,按照Bless的响应,您可以像这样添加.json

content: ["./src/**/*.{js,jsx,ts,tsx,json}"],

最后我有了这段代码,在我看来它更好。

import PokemonTypeMap from "./pokemonTypeMap.json";

function PokemonType(props) {
  const pokemonType = PokemonTypeMap[props.type];

  return (
    <span className={pokemonType.classes + " p-1 px-3 rounded-3xl leading-6 lowercase text-sm font-['Open_Sans']"}>
      {pokemonType.text}
    </span>
  );
}

export default PokemonType;
iibxawm4

iibxawm47#

现在可以使用SafeListing
和顺风-安全-生成器包,以“预生成”我们的动态风格。
使用tailwind-safelist-generator,您可以基于一组模式为您的主题生成一个Safelist.txt文件。
顺风的JIT模式扫描您的代码库中的类名,并根据找到的内容生成CSS。如果没有明确列出类名,如Text-${Error?‘red’:‘green’}-500,TailWind不会发现它。为了确保生成这些实用程序,您可以维护一个明确列出它们的文件,就像项目根目录中的Safelist.txt文件一样。

相关问题