概要
shadcn/ui
ライブラリのユーティリティ関数 cn()
は、複数の CSS クラス名を結合し、Tailwind CSS のクラス名の競合を解決する便利な関数です。
この記事では、この cn()
関数の仕組みと使用方法について解説します。
shadcn/ui のユーティリティ関数 cn()
以下が cn()
関数の実装コードです。
この関数は、clsx
と tailwind-merge
の 2 つのライブラリを組み合わせて実装されています。
import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
インポート
まず、clsx
と tailwind-merge
の 2 つのライブラリをインポートしています。
- clsx: 条件付きでクラス名を結合するためのライブラリです。オブジェクトのキーが true と評価される場合、そのキーがクラス名として結合されます。
- tailwind-merge: Tailwind CSS のクラス名の競合を解決するためのライブラリです。複数のクラス名が競合する場合、正しいクラス名を選択して返します。
cn() 関数
cn()
関数は、可変長引数 (...inputs
) を受け取り、それらを clsx()
関数に渡してクラス名を結合します。
次に、その結果を twMerge()
関数に渡してクラス名の競合を解決します。
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
使用例
以下は、cn()
関数の使用例です。
import { cn } from "./lib/utils";
function ExampleComponent({ isActive }) {
return (
<div
className={cn("base-class", isActive && "active-class", "another-class")}
>
Example
</div>
);
}
この例では、isActive
が true
の場合にのみ active-class
がクラス名として追加されます。
また、twMerge
がクラス名の競合を解決します。
clsx()
clsx()
は、条件付きでクラス名を結合するための関数です。
渡された値のうち、0
、false
、""
といった偽と評価される要素は無視し、それ以外を 1 つの文字列に結合します。
import { clsx, type ClassValue } from "clsx";
// Strings (可変長引数)
clsx("foo", true && "bar", "baz");
//=> "foo bar baz"
// Objects
clsx({ foo: true, bar: false, baz: isTrue() });
//=> "foo baz"
// Objects (可変長引数)
clsx({ foo: true }, { bar: false }, null, { "--foobar": "hello" });
//=> "foo --foobar"
// Arrays
clsx(["foo", 0, false, "bar"]);
//=> "foo bar"
// 入れ子の Arrays (可変長引数)
clsx(["foo"], ["", 0, false, "bar"], [["baz", [["hello"], "there"]]]);
//=> "foo bar baz hello there"
// Kitchen sink (with nesting)
clsx(
"foo",
[1 && "bar", { baz: false, bat: null }, ["hello", ["world"]]],
"cya"
);
//=> "foo bar hello world cya"
twMerge()
Tailwind CSS でスタイリングする際に、同じ要素に対して複数のクラス名が適用される場合、競合が発生することがあります。
twMerge()
関数は、このような競合を解決し、最終的に適用されるクラス名を決定します。
import { twMerge } from "tailwind-merge";
const className = twMerge("bg-red-500", "bg-blue-500");
// => "bg-blue-500"
競合するクラスは最後に指定されたクラスが優先されます。
この例では、bg-red-500
と bg-blue-500
の両方が指定されていますが、twMerge
は最後に指定された bg-blue-500
を適用します。
コメント