菜单

暗模式

相关源文件

本文档解释了 shadcn/ui 中深色模式的实现,涵盖了主题架构、特定于框架的实现和组件集成。有关 CSS 变量和颜色自定义的信息,请参阅 CSS 变量系统。有关深色模式以外更广泛的主题自定义,请参阅 主题自定义

架构概述

shadcn/ui 的深色模式系统采用基于 CSS 类的方法,通过在文档元素上切换 dark 类来应用主题。该系统支持三种主题模式:light(浅色)、dark(深色)和 system(遵循用户操作系统偏好)。

主题提供者架构

来源:apps/www/content/docs/dark-mode/next.mdx20-32 apps/www/content/docs/dark-mode/vite.mdx35-76 apps/www/components/providers.tsx9-20

特定于框架的实现

由于渲染、水合和状态管理的差异,每种框架在实现深色模式时都需要不同的方法。

按框架实现的模式

来源:apps/www/content/docs/dark-mode/next.mdx1-69 apps/www/content/docs/dark-mode/vite.mdx1-150 apps/www/content/docs/dark-mode/astro.mdx1-121 apps/www/content/docs/dark-mode/remix.mdx1-160

Next.js 实现

Next.js 实现使用 next-themes 包进行主题管理,并支持水合安全渲染。

核心组件

组件文件路径目的
ThemeProvidercomponents/theme-provider.tsx包装 NextThemesProvider
ModeToggle组件预览主题切换 UI
根布局app/layout.tsx提供者集成

apps/www/content/docs/dark-mode/next.mdx47-54 中的 ThemeProvider 组件配置使用了:

  • attribute="class" - 通过 CSS 类应用主题
  • defaultTheme="system" - 默认为操作系统偏好
  • enableSystem - 启用系统主题检测
  • disableTransitionOnChange - 防止过渡闪烁

位于 apps/www/content/docs/dark-mode/next.mdx44html 元素上的 suppressHydrationWarning 属性可防止 SSR 期间的水合不匹配。

来源:apps/www/content/docs/dark-mode/next.mdx18-60 apps/www/components/providers.tsx9-20

Vite 实现

Vite 实现使用自定义主题提供程序,该程序通过 React Context 和手动 DOM 操作构建。

主题提供程序结构

位于 apps/www/content/docs/dark-mode/vite.mdx35-76 的自定义 ThemeProvider 实现:

  • Theme 类型:"dark" | "light" | "system"
  • 用于状态管理的 ThemeProviderContext
  • 使用 storageKey 进行 localStorage 持久化
  • 直接进行 documentElement.classList 操作
  • 通过 matchMedia 进行系统主题检测

位于 apps/www/content/docs/dark-mode/vite.mdx78-85useTheme hook 提供主题状态访问和更新。

来源:apps/www/content/docs/dark-mode/vite.mdx10-150

Astro 实现

Astro 实现使用内联脚本即时应用主题,并使用 React 组件处理用户交互。

内联主题脚本

位于 apps/www/content/docs/dark-mode/astro.mdx17-34 的脚本负责:

  • 处理主题检测的 getThemePreference() 函数
  • 即时应用 dark
  • 用于持久化的 MutationObserver
  • 防止未样式内容闪烁

位于 apps/www/content/docs/dark-mode/astro.mdx57-97ModeToggle 组件使用 React 状态和 client:load 指令进行水合。

来源:apps/www/content/docs/dark-mode/astro.mdx10-121

Remix 实现

Remix 实现使用服务器端会话存储和 remix-themes 包进行兼容 SSR 的主题。

会话管理

主要组成部分包括:

位于 apps/www/content/docs/dark-mode/remix.mdx74-103 的根布局集成了主题系统,并进行适当的 SSR 处理。

来源:apps/www/content/docs/dark-mode/remix.mdx21-160

模式切换组件

所有框架实现都包含标准化的模式切换组件,具有一致的 UI 模式。

切换组件结构

切换组件使用

  • 来自 lucide-reactSunMoon 图标
  • 使用 dark: 修饰符进行 CSS 过渡
  • 用于可访问性的 sr-only 文本
  • 用于主题选择的下拉菜单

来源: apps/www/content/docs/dark-mode/next.mdx66 apps/www/content/docs/dark-mode/vite.mdx110-147 apps/www/content/docs/dark-mode/astro.mdx75-96 apps/www/content/docs/dark-mode/remix.mdx134-156

CSS 集成

深色模式通过基于类的主题切换与 CSS 变量系统集成。dark 类会触发 CSS 变量中定义的替代颜色值。

主题应用流程

主题系统会修改 documentElement.classList 以启用 CSS 选择器,例如

  • .dark .component-class
  • dark:bg-background
  • dark:text-foreground

这种方法允许组件根据活动主题类自动调整其外观。

来源: apps/www/content/docs/dark-mode/vite.mdx45-61 apps/www/content/docs/dark-mode/astro.mdx24-25 apps/www/content/docs/dark-mode/remix.mdx15-18