Skip to content

Latest commit

 

History

History
125 lines (86 loc) · 4.59 KB

antd-theme.md

File metadata and controls

125 lines (86 loc) · 4.59 KB

antd引入和主题切换

目录:/rendering/src/app/antd [查看]

演示:开发环境,请无视系统卡顿,只关注无闪烁 + 跟随系统自动切换

QQ20240304-043855-HD.mp4

引入andt

这次官方发布了一个包@ant-design/nextjs-registry[查看],原理和之前封装的方法一样,通过useServerInsertedHTML将初始的样式发送到header,这是由NextJS的css-in-js提供的解决方案[查看]。

antd发的这个包的目的就是省去了自己封装,只要在根目录布局文件中layout.tsx引入:

            <body className={inter.className}>
                <AntdRegistry>{children}</AntdRegistry>
            </body>

注意点:

主题切换

antd v5采用css-in-js的解决方案,切换主题需要:

产生的问题:

  • 主题闪烁

解决主题闪烁

官方提供的方式是通过cookies,见antd-style文档[查看]。通过server action记录操作,并以cookies提供给ConfigProvider切换主题:

    const cookieStore = cookies();
    const appearance = (cookieStore.get("theme")?.value || "auto") as ThemeMode;

    async function changeTheme(theme: ThemeMode) {
        "use server";
        theme === "auto" ? cookies().delete("theme") : cookies().set("theme", theme);
        revalidatePath("/");
    }

    return (
        <WithTheme darkTheme={appearance === "dark"}>
        </WithTheme>

产生的问题:

  • 以上操作均在服务端,在用户没有设置cookies之前,没办法获取到本地系统的主题

适应本地系统主题

通过CSS提权来实现,在此之前我需要在html中挂起当前主题是已手动配置还是随系统

    const cookieStore = cookies();
    const appearance = cookieStore.get("theme")?.value || "auto";
    return (
        <html lang="en" data-theme={appearance}>
        </html>
    );

当跟随主题的时候通过css提权设置默认主题,见global.css[查看]

html[data-theme="dark"] {
  color-scheme: dark;
}

html[data-theme="light"] {
  color-scheme: light;
}

@media (prefers-color-scheme: dark) {
  html[data-theme="auto"] {
    color-scheme: dark;
  }
  html[data-theme="auto"] body {
    color: rgb(var(--foreground-rgb));
  }
}

需要理清一个顺序:

  • antd默认提供3个算法[查看],除了手动设置为dark之外,默认就是light
  • 所以如果本地主题也是light不需要提权,只要关心本地是否是暗黑主题

于是:

/* 当本地是暗黑主题 */
@media (prefers-color-scheme: dark) {
  /* 且当前主题为跟随系统时 */
  html[data-theme="auto"] {
    color-scheme: dark;
  }
}

提醒:

  • Demo只作为演示原理,并没有提供所有antd黑暗主题的变量
  • 实际生产过程中,请自己参考以上方式,根据实际情况补完global.css

那这样就解彻底决闪屏问题了吗?

  • 已解决闪屏问题,但antd组件本身加载机制存在抖动,查看了一些tailwind组件,抖动情况稍好点,但仍旧存在抖动
  • 对于组件抖动这个问题还需要实际开发过程中根据实际情况解决,不在这次研究中

写在最后

手动设置变量是不是很麻烦?可以参考这篇CSR的解决办法。

https://github.com/cgfeel/ant-design-style?tab=readme-ov-file#csr%E4%B8%BB%E9%A2%98%E5%88%87%E6%8D%A2%E6%97%A0%E9%97%AA%E7%83%81