programing

TailwindCss에서 클래스 이름을 동적으로 빌드합니다.

megabox 2023. 3. 5. 09:41
반응형

TailwindCss에서 클래스 이름을 동적으로 빌드합니다.

현재 TailwindCss로 다음 프로젝트를 위한 컴포넌트 라이브러리를 구축하고 있는데 Button 컴포넌트 작업 중에 작은 문제가 발생했습니다.

'primary' ★★★★★★★★★★★★★★★★★」'secondary'합니다.tailwind.config.js 이 을 '' 해 보겠습니다.Template literalsbg-${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>

은 브라우저 되며, '클래스 이름'이 됩니다.bg-primary-500적용된 스타일 탭에는 표시되지 않습니다.

여기에 이미지 설명 입력

테마는 다음과 같이 설정됩니다.

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

안 요. 돼요. 냥냥여가가가가bg-primary-500이치노

솔직히 JIT 컴파일러가 동적 클래스 이름을 선택하지 않았기 때문인지, 아니면 내가 잘못하고 있는지(아니면 tailWind를 사용하는 방법이 아닐 뿐) 궁금할 뿐입니다.

어떤 도움이라도 환영합니다. 잘 부탁드립니다!

그래서 이러한 작업 방식은 권장되지 않으며 JIT가 이를 지원하지 않는다는 것을 알게 된 후(후한 코멘트 덕분에)보다 'config' 기반의 접근방식으로 변경했습니다.

기본적으로 여러 소품들의 기본 구성으로 컨스턴트를 정의하고 컴포넌트에 적용합니다.유지 보수 작업이 좀 더 필요하지만, 그 일을 해낼 수 있습니다.

다음은 구성 예입니다. (현재 입력하지 않음) 및 더 나은 리팩터링을 위해 업로드되어 있지만 이해하실 수 있습니다.

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>

Tailwind CSS 클래스를 작성하는 방법은 권장되지 않습니다.Tailwind CSS 문서를 인용하면 JIT 모드에서도 지원되지 않습니다.「Tailwind에는 클라이언트측의 런타임은 포함되어 있지 않기 때문에, 클래스명은 빌드시에 정적으로 추출할 수 있을 필요가 있습니다.클라이언트상에서 변경되는 임의의 동적 값에 의존할 없습니다.」

편집: 2022년 도입 개선 - https://stackoverflow.com/a/73057959/11614995

테일윈드 CSS는 다이내믹클래스 이름을 지원하지 않습니다(여기를 참조).하지만, 이것을 성취할 수 있는 방법은 아직 있습니다.Vue3 어플리케이션에서 동적으로 빌드 클래스 이름을 사용해야 했습니다.아래의 코드 예를 참조하십시오.

빌드 시 사용 중인 클래스가 있는지 응용 프로그램을 검색하여 다른 모든 클래스를 자동으로 삭제합니다(여기를 참조하십시오).단, 이 있습니다.savelist클래스를 삭제에서 제외하는 데 사용할 수 있는 기능(일명 프로덕션으로 항상 이동함)입니다.

아래 샘플 코드를 작성했습니다.이 코드를 제 제작에 사용하고 있습니다.의 색깔과 합니다.colorValues array를 참조해 주세요.

클래스 이 the the the the the the this this this this this this this this this this this this 。safelist이 기능을 실장하면, 실전 가동에 css 데이터를 더 많이 보내거나, 사용하지 않는 css 클래스를 보내거나 하는 것에 주의해 주세요.

const colors = require('./node_modules/tailwindcss/colors');
const colorSaveList = [];
const extendedColors = {};
const colorValues = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900];

for (const key in colors) {
  

  // To avoid tailWind "Color deprecated" warning
  if (!['lightBlue', 'warmGray', 'trueGray', 'coolGray',  'blueGray'].includes(key))
  {
    extendedColors[key] = colors[key];
    for(const colorValue in colorValues) {
       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: extendedColors
   }
  },
  plugins: [
    require('tailwind-scrollbar'),
  ]

}

풍풍의 경우JIT를 하는 모드 또는 JITtailwind.config.js

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

2022년에 누군가 건너오면 - 나는 A를 택했다.Mrozek의 답변은 폐지된 경고와 비물체 팔레트를 반복하는 문제를 피하기 위해 몇 가지 수정을 가했다.

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: [],
}

조금 늦었을 수도 있지만, 이 실타래를 치고 있는 사람들에게는요.

이에 대한 가장 간단한 설명은 다음과 같다.

다이내믹 클래스명으로 세이프리스트를 설정하지 않으면 다이내믹클래스명은 기능하지 않습니다.

단, Dynamic Class는 완전한 순풍 클래스 이름만 있으면 정상적으로 동작합니다.

여기에 기재되어 있다

이것은 효과가 없을 것이다

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

하지만 이건 효과가 있어

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

상태

코드 내에서 항상 완전한 클래스 이름을 사용하는 한 Tailwind는 매번 모든 CSS를 완벽하게 생성합니다.

긴 설명

는 에 .module.exports.content에 inside inside inside tailwind.config.js또한 테일윈드 클래스는 클래스 속성 내에 있을 필요가 없으며 해당 파일에 풀클래스 이름이 존재하고 클래스 이름이 동적으로 생성되지 않는 한 코멘트된 행에 추가할 수도 있습니다.테일윈드는 해당 클래스의 스타일을 가져옵니다.

따라서 이 경우 파일 내의 모든 가능한 동적 클래스 값에 대해 다음과 같은 전체 클래스 이름을 입력하기만 하면 됩니다.

<button className={ color === 'primary' ? 'bg-primary-500' : 'bg-secondary-500'}>
    {children}
</button>

또는 내가 원하는 방법으로

<!-- bg-primary-500 bg-secondary-500 -->
<button className={`bg-${color}-500 `}>
    {children}
</button>

여기 또 다른 예가 있습니다. Vue이지만 아이디어는 모든 JS 프레임워크에서 동일합니다.

<template>
    <div :class="`bg-${color}-100 border-${color}-500 text-${color}-700 border-l-4 p-4`" role="alert">
        test
    </div>
</template>
<script>
    /* all supported classes for color props 
    bg-red-100 border-red-500 text-red-700
    bg-orange-100 border-orange-500 text-orange-700
    bg-green-100 border-green-500 text-green-700
    bg-blue-100 border-blue-500 text-blue-700
    */
    export default {
        name: 'Alert',
        props: {
            color: {type: String, default: 'red'}
        }
    }
</script>

그리고 그 결과는 이렇게 될 것이다.

<Alert color="red"></Alert> <!-- this will have color related styling-->
<Alert color="orange"></Alert> <!-- this will have color related styling-->
<Alert color="green"></Alert> <!-- this will have color related styling-->
<Alert color="blue"></Alert> <!-- this will have color related styling-->
<Alert color="purple"></Alert> <!-- this will NOT have color related styling as the generated classes are not pre-specified inside the file -->

이제 safe Listing을 사용할 수 있습니다.

테일윈드 세이프리스트 패키지로 다이내믹스 스타일을 "선제"할 수 있습니다.

tailwind-safelist-generator 를 사용하면 세이프리스트를 생성할 수 있습니다.패턴 세트를 기반으로 테마의 txt 파일을 만듭니다.

Tailwind의 JIT 모드는 코드 베이스에서 클래스 이름을 스캔하여 발견된 이름을 기반으로 CSS를 생성합니다.클래스 이름이 text-${error? 'red' : 'green'}-500과 같이 명시적으로 나열되지 않으면 Tailwind는 클래스 이름을 검색하지 않습니다.이러한 유틸리티가 확실하게 생성되도록 하기 위해 세이프리스트와 같이 명시적으로 리스트 되어 있는 파일을 유지할 수 있습니다.txt 파일을 프로젝트의 루트에 저장합니다.

Blessing의 말대로 v3에서는 이를 지원하도록 콘텐츠 어레이를 변경할 수 있습니다.

나 이거 먹었어

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 파일로 옮겼는데, 정상적으로 동작하고 있다고 생각했지만 브라우저 cache...그래서 Blessing의 응답에 따라 이렇게 .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;

를 사용하는 것이 좋습니까?dynamic classtailwind?

아니요.

사용.dynamic classestailwind-css권장하지 않습니다.tailwind사용하다tree-shaking즉, 소스 파일에 선언되지 않은 클래스는 출력 파일에 생성되지 않습니다.따라서 항상 다음을 사용하는 것이 좋습니다.

Tailwind-css 문서에 따르면

문자열 보간을 사용하거나 부분 클래스 이름을 함께 연결하면 테일윈드는 클래스 이름을 찾을 수 없으므로 대응하는 CSS를 생성하지 않습니다.

주변에 일거리가 없나요?

네.

마지막 수단으로 테일윈드는 세이프리스트 클래스를 제공합니다.

세이프리스팅은 최후의 수단이며 특정 콘텐츠에서 클래스 이름을 검색할 수 없는 경우에만 사용해야 합니다.이러한 상황은 드물기 때문에 이 기능은 거의 필요하지 않습니다.

당신의 예에서, 당신은 당신이 원하는 것은100 500 700색조정규식을 사용하여 원하는 색상을 모두 포함할 수 있습니다.pattern그리고 그에 따라 음영을 지정합니다.

참고: Tailwind가 강제로 생성하도록 할 수 있습니다.variants또, 다음과 같이 합니다.

tailwind.config.js

module.exports = {
  content: [
    './pages/**/*.{html,js}',
    './components/**/*.{html,js}',
  ],
  safelist: [
    {
      pattern: /bg-(red|green|blue|orange)-(100|500|700)/, // You can display all the colors that you need
      variants: ['lg', 'hover', 'focus', 'lg:hover'],      // Optional
    },
  ],
  // ...
}
추가: 자동화를 통해 모든 순풍 색상을safelist
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
  }

  // Define all of your desired shades
  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}`)  <-- You can add different colored text as well 
        colorSafeList.push(`bg-${colorName}-${shade}`)
      }
    })
  }
}

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

메모: 가능한 모든 답을 조합하여 가능한 모든 방법으로 답을 요약하려고 했습니다.도움이 되었으면 좋겠다

언급URL : https://stackoverflow.com/questions/69687530/dynamically-build-classnames-in-tailwindcss

반응형