【React】Swiperでドット(ページネーション)のカスタマイズ【Tailwind】

現場でReact(Next.js)を使う機会があった。

そこではスライダーのライブラリとしてSwiperを使用していた

swiperjs.com

そして、ドット(ページネーション)の色をデフォルトから変更したいという依頼があった
↓これ

https://swiperjs.com/demos


こういう時はSwiperコンポーネントのpaginationオプション内に下記オプションを設定してやる

renderBullet: (index, className) => {
  return `<span class="${className}"></span>`
}

※classNameには「swiper-pagination-bullet」というデフォルトで設定されるクラス名が入ってきていたので、このままだと特にカスタムする前と見た目には変わりがない

Tailwindを使用していたので、classを付与するだけで完了と思っていた

renderBullet: (index, className) => {
  return `<span class="${className} bg-red"></span>`
}

だが、これだとアクティブになっていないドットもすべて色が変わってしまうのだ
全体的に赤々としてしまう。
アクティブなドット以外は、デフォルトと同じように灰色になってほしい。今は。
だからといって、scssに書くことはしたくないのだった。

しかし、renderBulletにはとくにアクティブ、非アクティブを見分ける機能はない。
なのでTailwindのaddValiantプラグインを使う。
https://tailwindcss.com/docs/plugins#adding-variants

addVariant('optional', '&:optional')

これはhover:とかと同じで、hoverした時にスタイルを適用するのと同じように特定の状況下でスタイルを適用させる書き方だ
Handling Hover, Focus, and Other States - Tailwind CSS
それをカスタマイズすることで、特定のクラスが付いたときにスタイルを適用させることができると考えた
optionalにはコードで実際に使用するクラス名、&:optionalにはセレクタを書くようだ

なのでこう書いた(swiper-pagination-bullet-activeはアクティブになった時にSwiperが付けるクラス名)

addVariant('swiper-bullet-active', '.swiper-pagination-bullet-active')

そうしたらなんとエラーが発生

Tailwind CSS: Your custom variant `swiper-bullet-active` has an invalid format string. Make sure it's an at-rule or contains a `&` placeholder.

おそらく&か@をつけろと言われている。
CSSに明るくないのでどうして?誰?という気持ちになる。
@はメディアクエリを見たことがあるが…とにかくリファレンスを見てもなんとなく違いそうという結論に
アットルール - CSS&colon; カスケーディングスタイルシート | MDN

ではアンパサンドはなんだろうか
たしかに「&:optional'」と例にもくっついてきている
取りあえずつけてみるとエラーが発生しなくなったので、どのように出力されるのか見てみた

addVariant('swiper-bullet-active', '&.swiper-pagination-bullet-active')
renderBullet: (index, className) => {
  return `<span class="${className} swiper-bullet-active:!bg-red"></span>`
}
swiper-bullet-active\:\!bg-red.swiper-pagination-bullet-active

どうやらアンパサンドの位置に適用したいスタイルのクラスが来るようだ
cssセレクタ記載方法では、クラス名をつなげて書くとその両方のクラスを持つ要素に適用されるようなので、やりたいこととしてはあっている
実際に挙動も意図通りだったので無事解決できた。