夜中に開発していると、暗めのエディタと真っ白なサイトの切り替えがかなりしんどい。
実装としても面白そうなので、ダークテーマ導入を優先してみることにする。
Shadcn自体はもともとdark themeを導入しやすい仕組みになっている(後述)ので、Shadcnコンポーネントで構成している部分は殆ど調整が必要ないはず。
記事全般に使用しているLexicalは、Lexical独自のTheming機能を持っているので、そのあたりの調整が必要になってかなという事前の見積もり。
ダークテーマの基本的な機能に関してはnext-themesライブラリを使用。
選定理由
↓ライトモード時
<html class="light" style="color-scheme: light;">↓ダークモード時
<html class="dark" style="color-scheme: dark;">タブAでテーマを変更したときにテーマ設定をlocalStorageに書き込み、タブBはstorage eventをlistenすることによりテーマ変更を検知&反映できる。
Shadcn dark mode: https://ui.shadcn.com/docs/dark-mode/next
Shadcn自体がnext-themesを用いたテーマ管理を紹介しているということもあり、shadcn系のコンポーネントは基本的にうまくいった。
lucide-reactのアイコンも調整不要だった。
colorのデフォルト値にcurrentColorが使用されているため、アイコンを描画する箇所における文字色が反映されるようになっている。
hover:bg-gray-50のように、直接色を指定してしまっている箇所はhover:bg-accentに置き換えた。
accentという色トークン自体は、Shadcn導入で初期化を行うタイミングでtailwind.config.tsに追加されている。
theme: {
extend: {
...
colors: {
accent: {
DEFAULT: "hsl(var(--accent))",
foreground: "hsl(var(--accent-foreground))",
}
}
}
}--accentや--accent-foreground自体はglobal.css上に定義されている。
--accent: 0 0% 96.1%;
--accent-foreground: 0 0% 9%;Lexical EditorのThemeに関しては、EditorThemeはテーマによって分岐せずに一つに保った。EditorThemeで参照するEditor.module.cssのほうでtokenを使いながらテーマに応じたスタイルを充てるようにした。
具体的なスタイルの分岐に関してはCSSのレイヤに押し込めた状態にできたので良い感じ。