
Refine v5 定制 Chakra UI 主题从 RefineThemes 预设到自定义品牌色实战【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine在 Refine 中UI 层Chakra UI、Ant Design、MUI、Mantine 等与核心逻辑完全解耦因此你可以像使用任何原生 Chakra UI 应用一样自由定制设计与主题。本篇文章以仓库中的customization-theme-chakra-ui示例为主线讲解如何在 Refine v5 中接入RefineThemes预设主题、通过extendTheme定制品牌色、以及实现暗色模式切换。读完本文你将掌握 Refine Chakra UI 项目主题定制的完整路径并能对照refinedev/chakra-ui的源码理解其主题实现原理。一、主题定制在 Refine 中的整体思路Refine 本身是一个 headless 的 React 框架负责数据获取、认证、路由、表单状态等核心能力而 UI 组件由refinedev/chakra-ui这类集成包提供。这意味着主题定制发生在UI 集成包层面核心refinedev/core不参与任何样式决策refinedev/chakra-ui导出的RefineThemes、ThemedLayout、ErrorComponent等组件全部基于 Chakra UI 的ChakraProvider上下文工作你可以在不改动任何业务逻辑的前提下通过一个theme对象改变整个后台界面的观感。示例文档的定位正是如此它声明你可以通过 Refine 在项目中定制设计与主题并在customization-theme-chakra-ui示例中演示了定制默认主题后的完整 CRUD 应用。该示例的全部源码位于 examples/customization-theme-chakra-ui。二、快速运行示例示例的 README.md 给出了两种运行方式本地创建与 CodeSandbox 在线预览。在本地终端执行以下命令即可基于该示例初始化一个完整的 Refine 应用npm create refine-applatest -- --example customization-theme-chakra-ui初始化完成后进入项目目录并启动开发服务器npm install npm run dev从 package.json 可以看到该示例的核心技术栈与版本前提Node 需满足20依赖版本作用refinedev/core^5.0.12Refine 核心数据、认证、路由refinedev/chakra-ui^3.0.2Chakra UI 集成包主题、布局、CRUD 组件chakra-ui/react^2.5.1Chakra UI 底层组件库refinedev/simple-rest^6.0.1REST 数据提供器refinedev/react-table^6.0.1TanStack Table 集成refinedev/react-hook-form^5.0.4React Hook Form 集成refinedev/react-router^2.0.4React Router v7 路由集成react/react-router^19.1.0 / ^7.0.2React 与路由运行时三、入口集成用 ChakraProvider 挂载 RefineThemes主题定制的第一步发生在应用的根组件。查看示例的 src/App.tsx核心代码只有一处用ChakraProvider包裹整个Refine并把RefineThemes.Blue作为主题传入import { GitHubBanner, Refine } from refinedev/core; import { ErrorComponent, ThemedLayout, useNotificationProvider, RefineThemes, } from refinedev/chakra-ui; import { ChakraProvider } from chakra-ui/react; import dataProvider from refinedev/simple-rest; import routerProvider, { NavigateToResource, UnsavedChangesNotifier, DocumentTitleHandler, } from refinedev/react-router; import { BrowserRouter, Routes, Route, Outlet } from react-router; import { PostList, PostCreate, PostEdit, PostShow } from ./pages; import { Header } from ./components/header; const App: React.FC () { return ( BrowserRouter GitHubBanner / ChakraProvider theme{RefineThemes.Blue} Refine routerProvider{routerProvider} dataProvider{dataProvider(https://api.fake-rest.refine.dev)} notificationProvider{useNotificationProvider()} resources{[ { name: posts, list: /posts, show: /posts/show/:id, create: /posts/create, edit: /posts/edit/:id, }, ]} options{{ syncWithLocation: true, warnWhenUnsavedChanges: true, }} Routes Route element{ ThemedLayout Header{Header} Outlet / /ThemedLayout } Route index element{NavigateToResource resourceposts /} / Route path/posts Route index element{PostList /} / Route pathcreate element{PostCreate /} / Route pathedit/:id element{PostEdit /} / Route pathshow/:id element{PostShow /} / /Route Route path* element{ErrorComponent /} / /Route /Routes UnsavedChangesNotifier / DocumentTitleHandler / /Refine /ChakraProvider /BrowserRouter ); }; export default App;这段代码同时体现了 Refine v5 的几个标准接线routerProvider负责路由解析与导航由refinedev/react-router提供dataProvider指向演示用的 REST 接口https://api.fake-rest.refine.devThemedLayout提供带侧边栏、头部、内容区的标准后台布局并把自定义Header注入其中syncWithLocation让查询状态与 URL 同步warnWhenUnsavedChanges配合UnsavedChangesNotifier提示未保存的更改。四、RefineThemes 源码剖析七种预设主题是如何生成的示例中只写了一行theme{RefineThemes.Blue}但RefineThemes并非魔法常量。它定义在 packages/chakra-ui/src/theme/index.ts其实现揭示了 Refine 主题体系的设计首先内置七种预设色板分别映射到 Chakra UI 基础主题的不同颜色const refineCustomThemes { Blue: baseTheme.colors.blue, Purple: baseTheme.colors.purple, Magenta: baseTheme.colors.pink, Red: baseTheme.colors.red, Orange: baseTheme.colors.orange, Yellow: baseTheme.colors.yellow, Green: baseTheme.colors.green, };然后通过Object.keys(...).reduce为每个色板调用一次extendTheme批量生成RefineThemes.Blue、RefineThemes.Purple等七个主题对象见 theme/index.ts#L92-L124export const RefineThemes Object.keys(refineCustomThemes).reduce( (acc, key) { const themeName key as keyof typeof refineCustomThemes; return { ...acc, [key]: extendTheme({ config: { initialColorMode: system, }, styles: { global: (props: StyleFunctionProps) { const bgLight props.theme.colors.gray[50]; const bgDark props.theme.colors.gray[900]; return { html, body: { background: mode(bgLight, bgDark)(props), }, }; }, }, colors: { brand: refineCustomThemes[themeName], refine: { ...refineCustomColors, }, }, }), }; }, {}, ) as Recordkeyof typeof refineCustomThemes, RefineTheme;每个预设主题都做了三件事config.initialColorMode: system跟随操作系统偏好决定初始明暗模式全局背景色通过chakra-ui/theme-tools的mode()函数在浅色模式下使用gray.50、深色模式下使用gray.900作为html, body的背景实现明暗模式的全局响应注入brand与refine两组自定义颜色brand即所选主色板refine则定义布局组件的专用色彩。其中refine色板的结构在源码中定义如下const refineCustomColors { header: { bg: { light: baseTheme.colors.white, dark: baseTheme.colors.gray[800], }, }, sider: { bg: { light: baseTheme.colors.white, dark: baseTheme.colors.gray[800], }, header: { light: baseTheme.colors.white, dark: baseTheme.colors.gray[800], }, }, } as const;也就是说ThemedLayout中的头部header与侧边栏sider背景色会依据明暗模式在白色与gray.800之间切换这是 Refine 预设主题实现暗色模式适配的关键。五、自定义品牌色参考默认主题写出自己的 theme当七种预设色板不够用时你可以完全自定义。源码中导出的默认主题refineTheme见 theme/index.ts#L9-L43就是一个最佳范本它展示了如何通过 Chakra UI 的extendTheme一次性定制颜色、字体与全局样式import { extendTheme, baseTheme } from chakra-ui/react; export const refineTheme extendTheme({ config: { initialColorMode: system, }, fonts: { heading: Montserrat, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, body: Montserrat, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, }, styles: { global: () ({ html, body: { fontSize: 14px, }, }), }, colors: { brand: { 50: #E6FFFA, 100: #B2F5EA, 200: #81E6D9, 300: #4FD1C5, 400: #38B2AC, 500: #319795, 600: #2C7A7B, 700: #285E61, 800: #234E52, 900: #1D4044, }, sider: { background: #2A132E, collapseButton: #150A17, }, }, });从中可以看到自定义主题的两个核心要点brand色阶必须提供完整的 50900 十档色值因为RefineTheme接口要求brand具备这十个档位见 theme/index.ts#L74-L90Refine 的按钮、链接、高亮等组件都会按档位取色字体与全局样式同样在此处统一管理例如将全局字号收敛为 14px更适合管理后台的密集信息展示。自定义时你只需在项目中新建一个theme.ts写出类似上面的对象再替换入口处的主题即可import { ChakraProvider, extendTheme } from chakra-ui/react; const customTheme extendTheme({ colors: { brand: { /* 50 到 900 的十档色值 */ }, }, }); ChakraProvider theme{customTheme} Refine.../Refine /ChakraProvider六、暗色模式切换Header 中的 colorMode 控制主题定制不止于初始色板。示例自定义的 Header 组件 演示了如何在应用内动态切换明暗模式import { HamburgerMenu } from refinedev/chakra-ui; import { Box, IconButton, Icon, useColorMode } from chakra-ui/react; import { IconMoon, IconSun } from tabler/icons-react; export const Header () { const { colorMode, toggleColorMode } useColorMode(); return ( Box py2 px4 displayflex justifyContentspace-between alignItemscenter wfull bgchakra-body-bg height64px positionsticky top0 zIndex1 HamburgerMenu / IconButton variantghost aria-labelToggle theme onClick{toggleColorMode} Icon as{colorMode light ? IconMoon : IconSun} w18px h18px / /IconButton /Box ); };关键点useColorMode()与toggleColorMode()来自chakra-ui/react与 Refine 无耦合任何 Chakra UI 应用都能直接使用由于预设主题的initialColorMode为system切换只影响当前会话的显示模式不会破坏跟随系统的初始行为HamburgerMenu由refinedev/chakra-ui导出用于控制ThemedLayout侧边栏的折叠展开它与主题色板sider色组协同工作。七、主题下的页面组件列表、筛选与表单如何响应主题换肤的效果最终要落到页面组件上。示例以posts资源为例实现了完整的 list / create / edit / show 四个页面它们全部复用refinedev/chakra-ui导出的List、Create、Edit、Show以及ShowButton、EditButton、DeleteButton、DateField等组件因此只需切换主题对象整套 CRUD 界面就会随之变色。以列表页 src/pages/posts/list.tsx 为例它演示了三个值得关注的点useTable来自refinedev/react-table返回的reactTable对象直接对接 TanStack Table配合 Chakra 的Table、Thead、Th等组件渲染列级筛选与排序由自定义的 ColumnFilter 和 ColumnSorter 组件实现其中status列的meta.filterElement直接渲染了一个 ChakraSelect下拉选项published / draft / rejected会继承当前主题的表单样式关联数据通过useMany加载分类名称从categories资源批量获取后通过table.options.meta注入表格上下文再在category.id列的cell中映射展示。而表单页如 src/pages/posts/create.tsx使用refinedev/react-hook-form的useForm表单控件FormControl、Input、Select、FormErrorMessage全部来自 Chakra UI同样会自动套用当前主题的配色与焦点样式无需任何额外配置。八、版本与使用前提本文所述内容基于当前仓库中的 Refine v5refinedev/core^5.0.12与refinedev/chakra-ui^3.0.2示例运行需要 Node20RefineThemes的七种预设色板Blue、Purple、Magenta、Red、Orange、Yellow、Green定义于 packages/chakra-ui/src/theme/index.ts其中Magenta实际映射的是 Chakra 的pink色板从源码结构看这是刻意为之的命名映射由于 Refine 将 UI 与核心解耦本文介绍的主题定制方案仅作用于refinedev/chakra-ui相关组件与自定义的 Chakra 组件不会影响 headless 层的数据与状态逻辑——这正是想换主题就换主题业务代码零改动的灵活性来源。总而言之Refine Chakra UI 的主题定制路径可以浓缩为三步在ChakraProvider挂载RefineThemes.*预设或自定义extendTheme产物 → 通过ThemedLayout与自定义Header承接布局与明暗切换 → 业务页面复用集成包的 CRUD 组件自动换肤。对照源码查看 theme/index.ts 的reduce生成逻辑你还可以按同样的模式扩展出属于自己的品牌色预设。【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考