You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ClojureScript中引入Joy UI暗黑模式并转译代码?

Joy UI暗黑模式在ClojureScript(shadow-cljs)中不生效的排查线索

问题背景

在ClojureScript项目(使用shadow-cljs)中尝试引入Joy UI暗黑模式,转译官方示例代码后主题与暗黑模式未生效,怀疑问题出在CssVarsProvider的引入环节。

官方示例代码

import * as React from 'react';
import { CssVarsProvider, extendTheme } from '@mui/joy/styles';
import Sheet from '@mui/joy/Sheet';
import Chip from '@mui/joy/Chip';
import Typography from '@mui/joy/Typography';

const theme = extendTheme({ cssVarPrefix: 'demo' });

export default function DarkModeByDefault() {
  return (
    <CssVarsProvider
      defaultMode="dark"
      // the props below are specific to this demo,
      // you might not need them in your app.
      //
      theme={theme}
      // the selector to apply CSS theme variables stylesheet.
      colorSchemeSelector="#demo_dark-mode-by-default"
      //
      // the local storage key to use
      modeStorageKey="demo_dark-mode-by-default"
      //
      // set as root provider
      disableNestedContext
    >
      <div id="demo_dark-mode-by-default">
        <Sheet sx={{ px: 3, py: 1.5, borderRadius: 'sm' }}>
          <Typography
            component="div"
            endDecorator={
              <Chip variant="outlined" color="primary" size="sm">
                Default
              </Chip>
            }
            fontSize="lg"
          >
            Dark mode
          </Typography>
        </Sheet>
      </div>
    </CssVarsProvider>
  );
}

我的转译代码

(ns ....
  (:require
    ...
   ["@mui/joy/Button" :as mui-joy-button]
   ["@mui/joy/Grid" :as mui-joy-grid]
   ["@mui/joy/styles" :as mui-joy-styles]))

(def btn (rc/adapt-react-class (.-default mui-joy-button)))
(def grd (rc/adapt-react-class (.-default mui-joy-grid)))
(def cvp (rc/adapt-react-class mui-joy-styles/CssVarsProvider))
(def ext mui-joy-styles/extendTheme)

(def theme (ext {:cssVarPrefix "demo"}))

(defn main-page []
  [cvp {:defaultMode "dark"
        :theme theme
        :colorSchemeSelector "#demo_dark-mode-by-default"
        :modeStorageKey "demo_dark-mode-by-default"
        :disableNestedContext true}]
  [:div {:id "demo_dark-mode-by-default"}
   [grd {:container true :spacing 2}
    [grd {:xs 8} [:p "asdasdfasdf"]]
    [grd {:xs 4} [btn {:variant :solid} "asdf"]]]])

排查线索

  • 组件嵌套错误:你的main-page函数中,[cvp ...]与后续:div是同级元素,而非嵌套关系。React要求Provider的子元素必须包裹在其内部,正确写法应为:

    (defn main-page []
      [cvp {:defaultMode "dark"
            :theme theme
            :colorSchemeSelector "#demo_dark-mode-by-default"
            :modeStorageKey "demo_dark-mode-by-default"
            :disableNestedContext true}
       [:div {:id "demo_dark-mode-by-default"}
        [grd {:container true :spacing 2}
         [grd {:xs 8} [:p "asdasdfasdf"]]
         [grd {:xs 4} [btn {:variant :solid} "asdf"]]]]])
    

    这是最可能导致主题不生效的原因——子组件未被CssVarsProvider包裹,无法获取主题变量。

  • CssVarsProvider引入验证:确认mui-joy-styles/CssVarsProvider的引用是否正确。在JS中它是命名导出,ClojureScript直接引用的写法没问题,但可通过shadow-cljs编译后的浏览器控制台检查是否有组件未找到的报错。

  • 主题变量与选择器匹配检查:验证页面渲染后,id="demo_dark-mode-by-default"的元素是否存在,通过浏览器开发者工具查看该元素是否被注入了Joy UI的CSS主题变量。

  • 依赖版本兼容性:检查@mui/joy与shadow-cljs的版本是否兼容,尝试升级到两者的最新稳定版,排除旧版本的兼容性问题。

  • 本地存储干扰排查:modeStorageKey设置的本地存储键若存在旧值,会覆盖defaultMode的设置,可先清除对应本地存储数据后重新测试。

内容的提问来源于stack exchange,提问作者Darren Kim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 13:45:12