GithubHelp home page GithubHelp logo

コンポーネントのPropsとして受け取ったTailwindのユーティリティクラスを、優先して適用させられるようにする about shikosai32-front HOT 12 CLOSED

3i-shikosai32 avatar 3i-shikosai32 commented on June 10, 2024
コンポーネントのPropsとして受け取ったTailwindのユーティリティクラスを、優先して適用させられるようにする

from shikosai32-front.

Comments (12)

dino3616 avatar dino3616 commented on June 10, 2024

Props.classNamefont-semiboldを指定したとき、

  • コンポーネントの定義を優先する場合
{/* font-boldが優先される */}
<div className={`${className} font-bold`}>
  • Props.classNameを優先する場合
{/* font-semiboldが優先される */}
<div className={`font-bold ${className}`}>

の二つの選択肢があるけど、でもどっちにしろコンポーネントの定義見ないと使用者は予期せぬ動作を引き起こしてしまうからどうにかしないとヤバくね?

って話で合ってる?

from shikosai32-front.

ReoHakase avatar ReoHakase commented on June 10, 2024

それも大事じゃないわけではないけど、自分が今回issueを立てた理由は、
Tailwindが出力したCSSコードの中で、コンポーネント内部で指定した.bg-neutral-900が外部から指定した.bg-success-700よりもあとに来てしまうと、${className}の挿入箇所に関わらずスタイルが上書きできなかったから↓
image
image
だからコード上で明確に優先順位を指定できるようにしなければいけないんだけど、それをどうやって実現するのか考えてる

from shikosai32-front.

dino3616 avatar dino3616 commented on June 10, 2024

あー普段の実装では気にしてなかったけど、StoryBookで起こった問題かこれ

from shikosai32-front.

ReoHakase avatar ReoHakase commented on June 10, 2024

image
${className}の位置を最後から最初に変更した場合も同様
image

import type { FC } from 'react';
import { MdAccessibilityNew } from 'react-icons/md';
import { Button, ButtonIcon } from '@/components/Button';

const Index: FC = () => (
  <main className="flex min-h-screen w-screen items-center justify-center">
    <div className="rounded-3xl bg-gradient-to-br p-8 gradient-primary">
      <h1 className="font-branding text-4xl font-bold text-white">Hello OZ at 茨城高専</h1>
      <Button className="bg-success-700" type="button">
        <ButtonIcon>
          <MdAccessibilityNew />
        </ButtonIcon>
        <i>react-icon</i>を使ったボタン
      </Button>
    </div>
  </main>
);

export default Index;

CSSの詳細度に依る問題だから、やっぱりStorybookの外でも同様だった

from shikosai32-front.

dino3616 avatar dino3616 commented on June 10, 2024

したがって、その優先順位は記述されたCSSがより後に読み込まれたものが優先される。

理解力が足りてなくて申し訳ないが、つまりどうあがいてもコンポーネントの定義のclassNameが優先されるってこと?

from shikosai32-front.

ReoHakase avatar ReoHakase commented on June 10, 2024

そうなんだよねえ
TailwindがJITで吐き出す順によるから、運良く外部指定のクラスが後に来た時は上書きができる...んだよね、実はさっきまで適切に上書きできてたし

from shikosai32-front.

dino3616 avatar dino3616 commented on June 10, 2024

ひとつごり押し解決策を思いついた。

  1. 予めコンポーネントで使うclassNameconst className = で定義しておく。(例: const className = "flex")
  2. props.classNameclassNameと競合するスタイルがないかを調べる。あればコンフリクトを解決する。
  3. classNameprops.classNameをmergeする。

from shikosai32-front.

dino3616 avatar dino3616 commented on June 10, 2024

うーん、やっぱ至難の業すぎるのでこれはダメだな。

from shikosai32-front.

ReoHakase avatar ReoHakase commented on June 10, 2024

その3: tailwind-overrideclassName内で使う

参考: Zenn.dev

  • .tailwind.config.jsを読み取ってカスタムクラスまで対応してくれるのかが不明
  • CSSの詳細度の問題をJS/TS側で無理やり対処しているところがすっきりしない
  • GitHubのスター数が84で頼りない

これがその案とほぼ同じことをやってるけど、結局propsを受け渡すたびにコンフリクトがないかどうか計算してるからパフォーマンス的にあまりよくない (要検証) と思う

from shikosai32-front.

dino3616 avatar dino3616 commented on June 10, 2024

それを使う or 例えばカラーを外から指定したいだけであれば、color: "red"|"green"|stringみたいなPropsを定義して、bg-${color}をすればいい。
パフォーマンスについてはそれほど気にしなくてもいいわけではないけど、まぁそれくらいなら...。

from shikosai32-front.

dino3616 avatar dino3616 commented on June 10, 2024

(これを言ってしまうと元も子もないけど、ここまで来ると多分外部からclassNameで指定すること自体アンチパターンな気がする...)

from shikosai32-front.

ReoHakase avatar ReoHakase commented on June 10, 2024

tailwind-merge

import { twMerge } from 'tailwind-merge'

twMerge('px-2 py-1 bg-red hover:bg-dark-red', 'p-3 bg-[#B91C1C]')
// → 'hover:bg-dark-red p-3 bg-[#B91C1C]'

クラス名に対立(Conflict)する複数のTailwindユーティリティクラスが存在する場合、後ろのものを優先して抜き出してくれる関数twMergeを提供するパッケージ。

  • キャッシュと遅延計算でパフォーマンスが考慮されている

Optimized for speed
Results get cached by default, so you don't need to worry about wasteful re-renders. The library uses a LRU cache which stores up to 500 different results. > The cache size can be modified or opt-out of by using extendTailwindMerge.
Expensive computations happen upfront so that twMerge calls without a cache hit stay fast.
These computations are called lazily on the first call to twMerge to prevent it from impacting app startup performance if it isn't used initially.

  • コンフィグを設定すれば.tailwind.config.jsに記述したgradient-*などの独自のクラスにも対応できる
  • GitHubスター数563と多め
  • 直近コミットが16日前

これで解決する方向性でいいかな?

from shikosai32-front.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.